Library provides RxJava2 wrappers for blocking JPA 2 operations written with Kotlin extension functions. Though it is pretty small in size it brings agility of kotlin and RxJava to the full power of JPA.
Hibernate 5.2.5.Final and EclipseLink 2.6.5, but should work with any other JPA 2 provider. Refer to tested providers for more information.
Add custom maven repository
repositories {
maven {
url 'http://nexus.eraga.net/content/repositories/public-releases/'
}
}
Add gradle dependency to your project:
// For JPA 2.2
compile "net.eraga.jpa.async:jpa2.2-rxjava2:1.2"
// For JPA 2.1
compile "net.eraga.jpa.async:jpa2.1-rxjava2:1.2"
// For JPA 2.0 (Required for those providers that are not compatible with JPA 2.1)
compile "net.eraga.jpa.async:jpa2.0-rxjava2:1.2"
Note
|
Latest version is 1.2
|
I assume you already had set up persistence.xml
file and know the basics of JPA.
Purely synthetic example how to retrieve and print a single Book title from database from cold start to release of connection:
lateinit var entityManager: EntityManager
lateinit var entityManagerFactory: EntityManagerFactory
RxPersistence
.createEntityManagerFactory("rxJpa2-test")
.flatMap {
entityManagerFactory = it
it.rxCreateEntityManager()
}.flatMap {
entityManager = it
it.rxFind(Book::class.java, 1)
}.subscribe { book ->
println(book.title)
entityManager.close()
entityManagerFactory.close()
}
Persistence
static class was extended via RxPersistence
kotlin object.
It has exactly the same methods as Persistence
except they are reactive.
RxPersistence
.createEntityManagerFactory("accountancy")
.observeOn(Schedulers.computation())
.map({
emf.createEntityManager()
})
.subscribe {
// do something with entityManager instance
}
On the other hand all blocking calls of EntityManagerFactory
, EntityManager
, Query
and TypedQuery
interfaces
have got extension functions.
For example TypedQuery.resultList
can be accessed in reactive way like that:
val entityManager: EntityManager = ... // instantiated somewhere else
entityManager
.createQuery("SELECT i From Employee i order by modified desc", Employee::class.java)
.rxResultList()
.subscribe {
// do something with List result
}
Persisting objects inside a single transaction have become much easier
entityManager
.rxTransaction {
it.persist(Book("Transaction book 1"))
it.persist(Book("Transaction book 2"))
it.persist(Book("Transaction book 3"))
it.persist(Book("Transaction book 4"))
}
.subscribe {
// do something on completion
}
Single persist operation is done inside a transaction
val book = Book("rxPersistBook")
entityManager
.rxPersist(book)
.subscribe {
// do something on completion
}
Each extension can accept a Scheduler
instance as an argument
// Custom Scheduler
entityManager
.createQuery("SELECT i From Employee i order by modified desc", Employee::class.java)
.rxResultList(Schedulers.computation())
.subscribe {
// do something with List result
}
Here is a brief example of using rxjava jpa2 helper library with Vertx DAO: https://stackoverflow.com/a/50244292/1824898
That was an initial goal of writing this library :)
All providers should be supported. Following providers had been tested with unit tests.
API Level | JPA Provider | Provider version | DB Engine |
---|---|---|---|
JPA 2.0 |
Hibernate |
4.2.2.Final |
H2 |
JPA 2.0 |
EclipseLink |
2.4.2 |
H2 |
JPA 2.1 |
Hibernate |
5.2.5.Final |
H2 |
JPA 2.1 |
EclipseLink |
2.6.5 |
H2 |
JPA 2.1 |
Kundera |
3.12 |
neo4j |
JPA 2.1 |
Kundera |
3.12 |
HBase |
JPA 2.1 |
Kundera |
3.12 |
RDBMS |
Warning
|
Kundera-RDBMS seems to be buggy, as it doesn’t pass certain tests while exactly same package of Hibernate (which it uses as a backend) passes all the tests. |