-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Attempt to Support fror @Inject StatelessSession #8861
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -139,6 +139,36 @@ WARNING: Make sure to wrap methods modifying your database (e.g. `entity.persist | |||||
CDI bean method `@Transactional` will do that for you and make that method a transaction boundary. We recommend doing | ||||||
so at your application entry point boundaries like your REST endpoint controllers. | ||||||
|
||||||
=== Processing raw or large amount of data | ||||||
|
||||||
`StatelessSession` are supported too and can be injected and used standalone or inter-mixed with your `EntityManager`. | ||||||
The benefits of `StatelessSession` are that entities are not put in a session-level cache, allowing for more raw and in some cases higher performance | ||||||
data access. Especially useful when reading/processing large amount of data. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and avoiding OutOfMemoryException while processing the data. |
||||||
|
||||||
[source,java] | ||||||
.Example application bean using Hibernate | ||||||
-- | ||||||
@ApplicationScoped | ||||||
public class SantaClausService { | ||||||
@Inject | ||||||
StatelessSession session; <.> | ||||||
|
||||||
@Transactional | ||||||
public void queryGifts(String giftDescription) { | ||||||
ScrollableResults gifts = session.getQuery("from Gift") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
.scroll(ScrollMode.FORWARD_ONLY); <.> | ||||||
while ( gifts.next() ) { | ||||||
Gift gift = (Gift) gifts.get(0); | ||||||
gift.updateStuff(...); | ||||||
session.update(customer); <.> | ||||||
} | ||||||
} | ||||||
} | ||||||
-- | ||||||
<.> Inject your stateless session and have fun; it will open or reuse the active transaction. | ||||||
<.> Using `scroll()` means you can process the data without loading the complete resultset or list of data in memory. | ||||||
<.> Since using a stateless session you need to explicitly call `update()` to save changes. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
[[hibernate-configuration-properties]] | ||||||
=== Hibernate ORM configuration properties | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package io.quarkus.hibernate.orm; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
|
||
import java.util.List; | ||
|
||
import javax.inject.Inject; | ||
|
||
import org.hibernate.StatelessSession; | ||
import org.jboss.shrinkwrap.api.ShrinkWrap; | ||
import org.jboss.shrinkwrap.api.spec.JavaArchive; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
import io.quarkus.arc.Arc; | ||
import io.quarkus.hibernate.orm.enhancer.Address; | ||
import io.quarkus.test.QuarkusUnitTest; | ||
|
||
/** | ||
* @author Max Rydahl Andersen <manderse@redhat.com> | ||
*/ | ||
public class StatelessSessionTest { | ||
|
||
@RegisterExtension | ||
static QuarkusUnitTest runner = new QuarkusUnitTest() | ||
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) | ||
.addClass(Address.class) | ||
.addAsResource("application.properties")); | ||
|
||
@Inject | ||
StatelessSession statelessSession; | ||
|
||
@Test | ||
public void testStatelessSession() { | ||
Arc.container().requestContext().activate(); | ||
try { | ||
List list = statelessSession.createNativeQuery("SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS") | ||
.addScalar("VALUE") | ||
.list(); | ||
assertNotNull(list); | ||
} finally { | ||
Arc.container().requestContext().terminate(); | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package io.quarkus.hibernate.orm.runtime; | ||
|
||
import javax.enterprise.inject.Produces; | ||
import javax.inject.Inject; | ||
import javax.inject.Singleton; | ||
import javax.persistence.EntityManagerFactory; | ||
|
||
import org.hibernate.SessionFactory; | ||
import org.hibernate.StatelessSession; | ||
|
||
public class DefaultStatelessSessionProducer { | ||
|
||
@Inject | ||
EntityManagerFactory em; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would probably fail if a custom There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would it fail? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, sorry. It would fail if a user-provided producer declares some qualifier... such as @Produces @PersistenceUnit(unitName="documents") @Documents EntityManagerFactory factory; But it's true that there is no reason to declare a producer like this if only one PU is supported... |
||
|
||
@Produces | ||
@Singleton | ||
StatelessSession produceStatelessSession() { | ||
return em.unwrap(SessionFactory.class).openStatelessSession(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,8 @@ | |
import javax.persistence.PersistenceContext; | ||
import javax.persistence.PersistenceUnit; | ||
|
||
import org.hibernate.StatelessSession; | ||
|
||
import io.quarkus.arc.Arc; | ||
import io.quarkus.arc.InstanceHandle; | ||
import io.quarkus.arc.ResourceReferenceProvider; | ||
|
@@ -56,8 +58,39 @@ public void destroy() { | |
}; | ||
} | ||
} | ||
} | ||
} else if (StatelessSession.class.equals(type)) { | ||
PersistenceContext pc = getAnnotation(annotations, PersistenceContext.class); | ||
if (pc != null) { | ||
if (jpaConfig.isJtaEnabled()) { | ||
TransactionEntityManagers transactionEntityManagers = Arc.container() | ||
.instance(TransactionEntityManagers.class).get(); | ||
ForwardingEntityManager entityManager = new ForwardingEntityManager() { | ||
|
||
@Override | ||
protected EntityManager delegate() { | ||
return transactionEntityManagers.getEntityManager(pc.unitName()); | ||
} | ||
}; | ||
return () -> entityManager; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like something fishy here, shouldn't you return CC @mkouba There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this should be used for If possible, I'd remove this code completely because @maxandersen What the use case for |
||
} else { | ||
EntityManagerFactory entityManagerFactory = jpaConfig.getEntityManagerFactory(pc.unitName()); | ||
EntityManager entityManager = entityManagerFactory.createEntityManager(); | ||
return new InstanceHandle<Object>() { | ||
|
||
@Override | ||
public Object get() { | ||
return entityManager; | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
entityManager.close(); | ||
} | ||
}; | ||
} | ||
} | ||
|
||
} | ||
return null; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think of it as read and forget.