如何使用Spring Data JPA方法在Kotlin的try-with-resources块中返回Stream?
所以我想使用Kotlin
创建一个使用Spring Data JPA
项目的Spring Boot
,并让我说我有一个Person
实体。 让我们这样说吧:
@Entity public class Person { private @GeneratedValue @Id Long id; private String name; @OneToMany private List<Person> friends; … }
我将创建以下接口,以便能够使用Try-with-Resources
和Stream<Person>
。
public interface PersonRepository extends Repository<Person, Long> { @Query("select p from Person p") Stream<Person> findAllStream(); }
所以通常在我的服务,我会这样做:
@Service class MyService { @Autowired 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()); } } }
现在,如果你想在Kotlin(IntelliJ转换器不生成有效的代码)中做到这一点。 我想你通常会这样做:
class MyService @Autowired constructor(val personRepository: PersonRepository) { fun foo() { val list = personRepository.findAllStream() .use {{p -> p.friends.stream()}.map {f -> f.name}} } }
只有你不能这样做,因为没有#use
方法在流,你不能从List
调用#stream()
。 那么有没有办法做到这一点?
那么,Java 8支持在Kotlin中还没有完成。 所以你可以像这样宣布在你身边使用
inline fun <A : AutoCloseable, R> A.use(block: (A) -> R): R { try { return block(this) } finally { close() } }
另一种方法是直接在Stream
上声明
inline fun <T, R> Stream<T>.use(block: (Stream<T>) -> R): R { try { return block(this) } finally { close() } }
UPD
如果您是Kotlin的新手,则必须注意,扩展名是静态解析的:
扩展实际上并不修改它们扩展的类。 通过定义扩展,不要将新成员插入到类中,而只需使用此类的实例上的点符号来调用新函数。
查看更多http://kotlinlang.org/docs/reference/extensions.html#extensions-are-resolved-statically
- Spring Data JPA + Guice错误:使用@EnableTransactionManagement注解时,没有类型的主要bean定义
- Kotlin脚本无法从jar中访问META-INF资源(persistence.xml)
- 重写Kotlin的财产二传导致两个JPA @Id
- 在Kotlin中使用JPA双向引用的StackOverflowError
- 与JPA Kotlin:默认构造函数地狱
- 如何禁用RepositoryRestHandlerMapping和EndpointHandlerMapping?
- 即使使用noarg插件,也没有使用Kotlin的JPA实体的默认构造函数
- Jpa Specification来查找字段值的子集
- JPA,Spring Data和Kotlin – 保存记录