There are many questions about this PersistenceException, but I have not seen some, where the specific line of code throws this exception only sometimes (but not randomly:-).
So, do you have any idea, why once my simple app finds the provider ok, but then later it won't?
NetBeans IDE 7.0.1, NetBeans Platform app, using persistence link library and Derby embbed.
I was trying this CRUD creatable capabilities "tutorial" by Geertjan, but i get the PersistenceException when saving new Trip:
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at org.mv.mm.api.TripSearchDAO.createTransactionalEntityManager(TripSearchDAO.java:61)
at org.mv.mm.api.TripSearchDAO.create(TripSearchDAO.java:41)
at org.mv.mm.api.TripQuery$3.create(TripQuery.java:69)
[catch] at org.mv.mm.api.TripType.create(TripType.java:64)
But in "search" method of DAO class, there is this private method createTransactionalEntityManager called too and EntityManager correctly created. Why it might be?
Ok, the problem is similar like many others here (well, I have not solved it, but I will try again tomorrow). It fails every time. I have mislooked the try catch block, so I did not noticed the exception. It occurs every time the Persistence.createEntityManagerFactory("TripPU").createEntityManager() is called.
In my opinion, this question is answered:
The reason, why the PersistenceException occurs only sometimes, is that the other time, when it seems, everything is OK, the problematic line:
em = Persistence.createEntityManagerFactory("TripPU").createEntityManager();
is called from another class from try... catch block, where the "catch" block does nothing. So I have not noticed that it fails always.
And the real solution to the real problem is also found: Really do check in those cases the name of your persistence unit in persistence.xml (like TripPU) if it is correct to the calling Persistence.createEntityManagerFactory("TripPU").createEntityManager();
The PU is not same as the DB entity, so the tutorials might you confuse when you try to do a bit different example (different tables etc.).
Related
My unit tests are seeing org.hibernate.LazyInitializationException: could not initialize proxy [org.openapitools.entity.MenuItem#5] - no Session. I'm not sure why they expect a session in a unit test. I'm trying to write to an in-memory h2 database for the unit tests of my Controller classes that implement the RESTful APIs. I'm not using any mock objects for the test, because I want to test the actual database transactions. This worked fine when I was using Spring-Boot version 1.x, but broke when I moved to version 2. (I'm not sure if that's what caused the tests to break, since I made lots of other changes. My point is that my code has passed these tests already.)
My Repositories extend JPARepository, so I'm using a standard Hibernate interface.
There are many answers to this question on StackOverflow, but very few describe a solution that I could use with Spring-Data.
Addendum: Here's a look at the unit test:
#Test
public void testDeleteOption() throws ResponseException {
MenuItemDto menuItemDto = createPizzaMenuItem();
ResponseEntity<CreatedResponse> responseEntity
= adminApiController.addMenuItem(menuItemDto);
final CreatedResponse body = responseEntity.getBody();
assertNotNull(body);
Integer id = body.getId();
MenuItem item = menuItemApiController.getMenuItemTestOnly(id);
// Hibernate.initialize(item); // attempted fix blows up
List<String> nameList = new LinkedList<>();
for (MenuItemOption option : item.getAllowedOptions()) { // blows up here
nameList.add(option.getName());
}
assertThat(nameList, hasItems("pepperoni", "olives", "onions"));
// ... (more code)
}
My test application.properties has these settings
spring.datasource.url=jdbc:h2:mem:pizzaChallenge;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=pizza
spring.datasource.password=pizza
spring.jpa.show-sql=true
This is not standard Hibernate, but spring data. You have to understand that Hibernate uses lazy loading to avoid loading the whole object graph from the database. If you close the session or connection to the database e.g. by ending a transaction, Hibernate can't lazy load anymore and apparently, your code tries to access state that needs lazy loading.
You can use #EntityGraph on your repository to specify that an association should be fetched or you avoid accessing the state that isn't initialized outside of a transaction. Maybe you just need to enlarge the transaction scope by putting #Transactional on the method that calls the repository and accesses the state, so that lazy loading works.
I found a way around this. I'm not sure if this is the best approach, so if anyone has any better ideas, I'd appreciate hearing from them.
Here's what I did. First of all, before reading a value from the lazy-loaded entity, I call Hibernate.initialize(item);
This throws the same exception. But now I can add a property to the test version of application.properties that says
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
Now the initialize method will work.
P.S. I haven't been able to find a good reference for Spring properties like this one. If anyone knows where I can see the available properties, I'd love to hear about it. The folks at Spring don't do a very good job of documenting these properties. Even when they mention a specific property, they don't provide a link that might explain it more thoroughly.
UPDATE
Liferay ticket accepted , solution in dev : https://issues.liferay.com/browse/LPS-82954
Situation
My context is a parallel import of liferay layouts through a liferay portlet; build with spring. When i´m executing it in Liferay dxp; the api call to add a Layout throws a StaleObjectStateException. (https://github.com/liferay/liferay-portal/blob/d969e0e839db9ea64267f7bff0a76be93cd26fa0/portal-impl/src/com/liferay/portal/service/impl/LayoutLocalServiceImpl.java)
This exception occurs when the api internally does an update on the corresponding LayoutSet (updating the PageCount for that Group, where the layout has been added to, just a single moment ago).
This does not happen in a single threaded execution!
Actions
Firstly i synchronized that call .. without any better results
meanwhile i read something about, that only synchronizing the threading won´t help, because the transaction itself may not be inside the synchronized execution block. therefore i also added a transactional annotation. .. without better results
so far i gained the following insight:
there is a Bug in the LayoutSetLocalService.updatePageCount(): the updated LayoutSet is not returned .. therefore the (with Liferay 7/DXP introduced) mvcc Version of the LayoutSet is not incremented. .. but this should not have any influences on my situation (https://github.com/liferay/liferay-portal/blob/7eb86ce5f6a7b2c9a405853a20fe81592e639219/portal-impl/src/com/liferay/portal/service/impl/LayoutSetLocalServiceImpl.java).
Can anybody give me a hint , whether there is any chance to tackle that ?
Or is this a consequence of the optimistic locking and i have to live with that?
did i missed a puzzle when creating the threads ? maybe some weird .. configurate my hibernate session ... thing ?
Code Excerpts
-> Test Project Available: https://github.com/andrebiegel/liferay-layout-issue.git
private static final Object layoutCreationLock = new Object();
synchronized (layoutCreationLock) {
newLayout = addLayoutApiCall(pageContext, serviceContext, typeSettings, friendlyURLMap);
}
#Transactional(propagation = Propagation.REQUIRES_NEW)
public Layout addLayoutApiCall(IPageContext pageContext, ServiceContext serviceContext, String typeSettings,
Map<Locale, String> friendlyURLMap) throws PortalException {
Layout newLayout;
newLayout = LayoutLocalServiceUtil.addLayout( pageContext.getProjectConfiguration().getUserId(), pageContext.getProjectConfiguration()
.getSiteId(), pageContext.isPrivatePage(), pageContext.getParentLayoutId(), pageContext
.getNamesMap(), pageContext.getTitleMap(), pageContext.getDescriptionMap(), pageContext
.getKeywordsMap(), pageContext.getRobotsMap(), pageContext.getPageType(), typeSettings,
pageContext.isHiddenPage(), friendlyURLMap, serviceContext );
return newLayout;
}
Unfortunately Liferay will not fix this. Ticket has been closed; declared as not a Use Case. The reason is that the solution produced negativ consequences in other use case. So Liferay seems to have an issue in their transaction management. by the way , i have also seen such Exceptions when concurrently adding Expandos.
I'm experiencing a weird/odd behavior. I'm working on a project which is a web app using Java EE. It is deployed on GlassFish 3.1.1 using Eclipselink 2.3 persistence services. Everything is on Eclipse, Windows 7 professional 64 bit, JDK + JVM 64 bit.
I get a business object to work with. First I set the corresponding entity. Everything is fine up to the invocation of a method. If I debug inside this, the entity suddenly becomes null.
Before this invocation the entity is instantiated.
The code is this:
// get my entity
tramiteProxy = ejbTramiteFactory.getEntity(tramite);
// get corresponding business thru factory
IRegistrableInLiquidador registrableInLiquidadorBusiness = (IRegistrableInLiquidador) ejbTramiteFactory.getCBusiness(tramiteProxy);
// invoke business
// up to here everything is fine, you can inspect business variable and it shows correct, entity is instantiated as expected
registrableInLiquidadorBusiness.registrarNovedadInIntegrador();
Now we go debugging inside the business object (registrableInLiquidadorBusiness):
// Here if one checks the entity it became null !!!
public void registrarNovedadInIntegrador() throws CException {
try {
CIntegradorBusiness ejbIntegradorBusiness = CCTX
.getEJB(CIntegradorBusiness.class);
// Here's the problem: getEntity() returns null, the entity of this business object became *magically* null
ejbIntegradorBusiness.registrarNovedad(getEntity(),null);
} catch (Exception e) {
throw new CException(1, e);
}
}
I must add that the object entity is a variable declared in the father of this business, from which it extends.
So I don't know what else to try. I looked at every single line of code that has to do with this for finding any mistake to no avail.
The next step would probably be downloading the Eclipselink source and debug it to see what's going on behind the scenes, though I don't even know if it has anything to do with this.
Any advice would be greatly appreciated.
I'm implementing an edited version of the Secure controller, default in the latest Play Framework.
I have read several times that, if you want to customize the Secure behaviour, you're better off copying the source of the Secure module, and start customizing it.
So I did, and after editing the needed dependencies I received following error:
Execution exception
NullPointerException occured : null
In /app/controllers/SecureController.java (around line 194)
190:
security = classes.get(0);
191:
}
192:
if(security==null)System.out.println("security is null");
193:
try {
194:
return Java.invokeStaticOrParent(security, m, args);
195:
} catch(InvocationTargetException e) {
196:
throw e.getTargetException();
197:
}
198:
}
199:
200:
}
The first logic conclusion to jump to is: there are no classes that implement the needed Secure$Security inner class. But there most certainly is a subclass, so I was wondering how this error can be fixed.
A debugging session learns that the classes.get(0) does contain the class that has the #With annotation. So the null pointer exception must be caused by something within the class that contains the #With(SecureController). But I left that class just the way it was, I just edited the reference within the With annotation.
So my guess is that somehow, there is a null pointer within the class implementation.
But even when I implement default behaviour, without any references, it still generates a nullpointerexception.
EDIT:
I found the cause of this error, but the 'why' isn't clear.
This line is found in the implementation of the authenticate(...) method in the subclass of SecureController$Security:
flash.put("url", request.url);
Why does this fail?
I understand this situation may be very hard to reproduce, but I was wondering if someone already experienced the same issue.
Thanks for the help (on many Play! related topics) so far.
the Scope.Flash class does not allow you to store null values. Perhaps you unset or failed to set request.url elsewhere in your modifications?
We are experiencing an exceedingly hard to track down issue where we are seeing ClassCastExceptions sometimes when trying to iterate over a list of unmarshalled objects. The important bit is sometimes, after a reboot the particular code works fine. This seems to point in the direction of concurrency/timing/race condition. I can confirm that neither the JAXBContext, nor the marshallers and unmarshallers are being used concurrently. We've gone as far as serializing access to them through locking.
However, since we run on an OSGi platform where individual bundles are getting initialized asynchronously through Spring DM it can be that 2 different bundles are creating their JAXBContext at the same time.
In any case I would appreciate any pointers towards an explanation for what could cause these intermittent ClassCastExceptions. The intermittent is important since they indicate that the code itself is normally working fine but that some external factor seems to influence the behaviour.
Here's a specific example of the exception (note I removed the company specific stuff):
Caused by: java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to com.foobar.TunnelType
at com.foobar.NetMonitorImpl.getVpnStatus(NetMonitorImpl.java:180)
That method at line 180 is a for() construct looping over a Collection of TunnelType objects inside of an unmarshalled object (said unmarshalling works fine BTW).
Given that the actual object unmarshalling went fine, is it even physically possible for JAXB to leave ElementNSImpl objects inside of nested collections?
Runtime environment:
JAXB 2.1
OSGi
Spring DM
The JAXBContext is initialised with the ClassLoader of the bundle containing the classes to be marshalled/unmarshalled
I get this exception ONLY when I forget to tell JAXBContext
about ALL to-be-marshalled types it could be dealing with.
JAXBContext.newInstance(MyClass1.class,MyClass2.class, [...]);
Neither of the approaches suggested here did it for me. However this resolved my problem
#XmlAnyElement(lax = true)
public List<Foo> foos;
Out of despair we turned to synchronizing on the JAXBContext.class object, seeing this as the only remaining possibility for some race condition and at least we have not been able to reproduce this issue again. Here's the critical code:
synchronized (JAXBContext.class) {
context = JAXBContext.newInstance(packageList, classLoader);
}
The synchronized clause above resolved the issue for me as well, but it seems like the context should not be a local variable. Instead it should be an instance variable, or a static. I wasn't able to refactor my code how I'd like it, so instead I moved the context into a static initializer, which isn't perfect, but seems to work:
private static Unmarshaller um;
static{
try {
final JAXBContext ctx = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName());
um = ctx.createUnmarshaller();
} catch (final JAXBException e) {
e.printStackTrace();
}
}