I'm starting a new project and I'm totally new to JPA/Hibernate use. I'm trying to understand how to use EntityManager properly. More precisely, when to instantiate them, how many do I need, should I close them, should I put everything into transactions?
Anyway, in my current code, I got an org.hibernate.LazyInitializationException while trying to read an entity that I previously saved. I would understand the opposite (reading an antity in a transaction then trying to save the read entity in another transaction but since transaction is over, the entity is unmanaged so save fails), but this I can't understand.
I put my code on GitHub (https://github.com/GaetanLeu/intl), it's just a couple of classes. My main is in src/sandbox/MessageSandbox.java and it fails at line 28 with the following stacktrace:
Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at entity.MessageKey_$$_jvstfcc_0.toString(MessageKey_$$_jvstfcc_0.java)
at java.lang.String.valueOf(String.java:2854)
at java.lang.StringBuilder.append(StringBuilder.java:128)
at com.google.common.base.Present.toString(Present.java:88)
at java.lang.String.valueOf(String.java:2854)
at java.io.PrintStream.println(PrintStream.java:821)
at sandbox.MessageSandbox.main(MessageSandbox.java:28)
Also I got a warning from Hibernate saying my EntityManager already exists, what happens then? Is the EntityManagerFactory.createEntityManager method returning the existing one?
WARN: HHH000436: Entity manager factory name (intl) is already registered. If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name'
Really I'm lost about when to create EntityManagers ^^ Any help would be appreciated, but please simple explanation I'm really new to this.
Oh BTW, I want to precise I'm not using Spring, I don't have EJBs, I want to manipulate EntityManagers manually for now until I understand it. Thanks :)
An entityManager manages a persistence context, in other word an in memory snapshot of the database state.
See What is a persistence object?
Every object loaded using the entityManager will be in managed state (see entity life cycle) until you close the EM. When an entity is managed
, all change made to it will be tracked and then persisted when flushing the EM. If you access some lazy fetched attribute, a request will be automatically triggered to dynamically load the data, but if the entity is in detached state (if EM have been closed) accessing a lazy attribute will lead to the error you get.
The scope (/lifecycle) of your EM depends of your execution context. For a web application for example, an EM will typically be created for each http request.
For a standalone application, you have to mind if the database can be updated by another application/thread or not. If it can, your persistent context may not be consistent with the database state and you should create it for every unit of work (transaction) to avoid that. Otherwise you can create a single instance once for all the application lifecyle and flush it regulary.
For a CRUD app the lifecycle is generally the following :
On user updates validation :
Keep is mind that EM is a lightweight object, cheap to create and destroy and NOT THREADSAFE.
BTW, JPA is a Java EE specification which is part of the EJB one (the persistence part). Its aim is to be used in a java EE container context (Java EE application server or CDI since JEE 6). You still can use hibernate in standalone mode through the JPA contract but even in this case, coupling with spring must be considered to take advantage of container managed features.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With