¿Cómo usar los methods Spring Data JPA que devuelven un Stream en un bloque try-with-resources en Kotlin?

Así que quiero crear un Spring Boot con Spring Data JPA project usando Kotlin y digamos que tengo una entidad Person . Digamos así:

 @Entity public class Person { private @GeneratedValue @Id Long id; private String name; @OneToMany private List<Person> friends; … } 

Crearía la siguiente interfaz para poder usar Try-with-Resources y Stream<Person> .

 public interface PersonRepository extends Repository<Person, Long> { @Query("select p from Person p") Stream<Person> findAllStream(); } 

Por lo tanto, normalmente en mi service, haría esto:

 @Service class MyService { @Autowinetworking PersonRepository repository; List<String> foo() { try(Stream<Person> stream = repository.findAllStream()) { return stream.flatMap(p -> p.getFriends().stream()) .map(f -> f.getName()) .collect(Collectors.toList()); } } } 

Ahora si quieres hacer esto en Kotlin (El convertidor IntelliJ no produce código válido). Supongo que normalmente harías algo como:

 class MyService @Autowinetworking constructor(val personRepository: PersonRepository) { fun foo() { val list = personRepository.findAllStream() .use {{p -> p.friends.stream()}.map {f -> f.name}} } } 

Solo que no puedes hacerlo porque no hay #use método #use en la transmisión y no puedes invocar #stream() desde una List . Entonces, ¿hay alguna manera de hacer esto?

    Bueno, el soporte de Java 8 aún no está completo en Kotlin. Entonces puedes declarar el uso de tu lado como este

     inline fun <A : AutoCloseable, R> A.use(block: (A) -> R): R { try { return block(this) } finally { close() } } 

    La otra alternativa es declararlo directamente en Stream

     inline fun <T, R> Stream<T>.use(block: (Stream<T>) -> R): R { try { return block(this) } finally { close() } } 

    UPD

    Si es nuevo en Kotlin, debe observar que las extensiones se resuelven estáticamente:

    Las extensiones en realidad no modifican las classs que extienden. Al definir una extensión, no inserta nuevos miembros en una class, sino que simplemente hace que nuevas funciones se puedan llamar con la notación de puntos en las instancias de esta class.

    Ver más http://kotlinlang.org/docs/reference/extensions.html#extensions-are-resolved-statically