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.
Related
This question is spawned from this ObjectDB forum posting, in the hope that the wider JPA community may be able to offer some insights. Some aspects may be specific to the ObjectDB implementation of JPA
objectdb-2.6.3_04
JDK1.7
VM option at runtime: -javaagent:lib/objectdb.jar
This problems only seems to occur in a specific large web application. I have a smaller test web application parallel to the large web application, but the problem does not happen in the smaller web application (as I will demonstrate below), so there is no point making that available here. I have been unable to find the point of difference. I showing selected portions of code from each below.
I am using pre-detach loading after em.find(id), because just relying on JPA-annotations, which is a "one size fits all" approach, does not meet my needs for all situations. I can configure an entity-query #EJB with a specific loader that - after the em.find(id) is performed - executes selected operations (while "visiting" the loaded managed entity) to load and fetch desired values.
In addition to the persistent fields my entities have transient computation methods, and calling these during the pre-detach loading should (and usually does) load everything needed to compute a transient expert system value, which should then be consistently re-computated once detached and used in a JSF web interface (not further shown here).
I won't give too many details about the entity classes, I will demonstrate the problem I am experiencing first, but you need to know that below:
A LightingZone is a subclass of entity Block
A Block has a property 'present' which is a "deep" Boolean value wrapper BooleanValue entity. This is #OneToOne with explicit LAZY fetch.
A BooleanValue entity wraps a simple Boolean property 'value'.
A LightingZone has a property 'v_NLA' which is a "deep" Float value wrapper FloatQuantity entity. This is #OneToOne with explicit LAZY fetch.
A FloatQuantity entity wraps a simple Float property 'value'.
(Also, the getL_LightingZone() below is a a generic List wrapping entity, with the list of LightingZone accessed via getL_LightingZone().getEls(). This plays no role in the problem encountered.)
The #OneToOne entity variable 'present' of a Block entity is a BooleanValue with:
#Entity
public class BooleanValue extends Value
{
public BooleanValue() {
}
private Boolean value;
public Boolean getValue() {
return value;
}
public void setValue(Boolean value) {
this.value = value;
}
...
(I won't go here into details about why such value wrappers are being used, but we have very good reasons, including being able to easily reference the "deep" value in an expert system.)
And the Block entity has:
private BooleanValue present;
#OneToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
public BooleanValue getPresent() {
return present;
}
public void setPresent(BooleanValue present) {
this.present = present;
}
It need not necessarily be fetch = FetchType.LAZY (if you set leave it as default fetch = FetchType.EAGER the problem reported here vanishes), but for performance reasons (and for the sake of demonstrating the problem described here) it is fetch = FetchType.LAZY (which hint ObjectDB respects).
The following from my real web fails to pre-detach load, it is failing to load the test within the indicated if statement:
#Transient
public Float getNLA_m2_LightingZone() {
Float sum = 0f;
if (getL_LightingZone() != null && getL_LightingZone().getEls() != null) {
for (LightingZone lz : getL_LightingZone().getEls()) {
if (lz.getPresent().getValue() != null && lz.getPresent().getValue()) { //FAILS TO LOAD getPresent().getValue()
//THIS IS NEVER REACHED, ALTHOUGH IN FACT lz.present.value IS true IN THE DATABASE
//lz.getPresent().getValue has NOT loaded ok for the test.
Float area = lz.getV_NLA().getValue();
if (area != null) {
sum += area;
} else {
return null;//POLICY
}
}
}
return sum;
} else {
return null;
}
}
But strangely (to me at least) this works, storing the test in a temporary variable:
test = lz.getPresent().getValue() != null && lz.getPresent().getValue();
if (test) {
// TEST NOW PASSES FINE: lz.getPresent().getValue has INDEED loaded ok for the test.
Float area = lz.getV_NLA().getValue();
There are some other things that also work if used before the if (lz.getPresent().getValue() != null && lz.getPresent().getValue()) test:
Logging the value of lz.getPresent().getValue() (or sending it to System.out).
Otherwise making some contrived usage of lz.getPresent().getValue() - before the if statement - that the compiler will not remove.
This does not work (is not enough) before the if statement test:
Just calling lz.getPresent().getValue() somewhere, but not using the result somehow (the compiler just removes it, for the loading to be triggered it has to be somehow stored in a variable that is eventually used OR just used for logging or output, confirmed using javap -c).
"Touching" the id with lz.getPresent().getId() before the if statement test.
It has to be the wrapped Boolean value, and it has to be outside and before that indicated if statement test.
I have very carefully (not shown here) also investigated the ObjectDB load states using Persistence.persistenceUtil() before and after that problematic if statement, and it is consistent with what is given above. The 'lz.present.value' and 'lz.v_NLA.value' are null and NOT loaded before the problematic if statement, and 'lz.present.value' is loaded (and true) afterwards, in those cases where it passes the if statement at all (because, for example, the temporary 'test' holder is used).
I tried to isolate it using a simpler test web app with exactly the same pre-detach loading strategy, but could not reproduce the problem. The following works WITHOUT storing the test in a temporary variable:
#Transient
public Float getComputed() {
Float val = 0f;
if (getL_InnerBlock() != null && getL_InnerBlock().getEls() != null) {
for (InnerBlock ib : getL_InnerBlock().getEls()) {
//ObjectDB PersistenceUtil claims neither ib.present.value nor ib.present.id are loaded.
if (ib.getPresent().getValue() != null && ib.getPresent().getValue()) {
//ObjectDB PersistenceUtil claims present.value now loaded.
if (f == null) {
return null;
} else {
val += f;
}
}
}
return val;
} else {
return null;
}
}
This test version does not suffer from the same problem, it runs fine without any "load touching" tricks, although the relevant if statement is apparently identical.
Therefore, a complete answer to this question/problem would explain why the trick with pre-loading and storing lz.present.value before the if statement might possibly be required in one case, but not the other (in other words, what the point of difference might be that I should test).
Ideally, I want to reproduce the problem in the test app to understand it fully.
It has taken me ages to finally find/identify this problem, as I did not imagine that performing the load access inside an if statement could make a difference (and after all, this did not cause problems in the mini test app). I have tried in vain to find any point of difference between the real web app and the mini test app, I am now truly bamboozled (hence this detailed forum posting).
For the brave, be warned that for this type of problem using a debugger is not the answer (at least, walking through with NetBeans debugger did not help me, as every time you inspect a variable it triggers loading of it, preventing discovery of the real problem.) Similarly, using debug logging can also trigger loading. It's the Schrödinger's cat of JPA.
I consider this a work-around, not a completely satisfactory answer.
ObjectDB support have helpfully reviewed this case and suggested I try using post-compile enhancement as an Ant task in build.xml , rather than relying on Load Time (Java Agent) Enhancement with this VM option:
-javaagent:lib/objectdb.jar
That agent does not enhance the compiled class files back into /build/web/WEB-INF/classes, it just enhances them as loaded into the JVM (in memory).
It is not (according to ObjectDB support) supposed to make a difference, but it definitely does in my operational environment (on deploying the web app to Glassfish4.1) and I have encountered other subtle differences elsewhere on other occasions. In any case, the reported problem disappeared when I used post-compile Ant task enhancement.
There must be a point of difference, but it remains to be identified.
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.).
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?
I have a code that saves a bean, and updates another bean in a DB via Hibernate. It must be do in the same transaction, because if something wrong occurs (f.ex launches a Exception) rollback must be executed for the two operations.
public class BeanDao extends ManagedSession {
public Integer save(Bean bean) {
Session session = null;
try {
session = createNewSessionAndTransaction();
Integer idValoracio = (Integer) session.save(bean); // SAVE
doOtherAction(bean); // UPDATE
commitTransaction(session);
return idBean;
} catch (RuntimeException re) {
log.error("get failed", re);
if (session != null) {
rollbackTransaction(session);
}
throw re;
}
}
private void doOtherAction(Bean bean) {
Integer idOtherBean = bean.getIdOtherBean();
OtherBeanDao otherBeanDao = new OtherBeanDao();
OtherBean otherBean = otherBeanDao.findById(idOtherBean);
.
. (doing operations)
.
otherBeanDao.attachDirty(otherBean)
}
}
The problem is:
In case that
session.save(bean)
launches an error, then I get AssertionFailure, because the function doOtherAction (that is used in other parts of the project) uses session after a Exception is thrown.
The first thing I thought were extract the code of the function doOtherAction, but then I have the same code duplicate, and not seems the best practice to do it.
What is the best way to refactor this?
It's a common practice to manage transactions at one level above DAOs, in services or other business logic classes. That way you can, based on the business/service logic, in one case do two DAO operations in one transaction and, in another case, do them in separate transactions.
I'm a huge fan of Declarative Transaction Management. If you can spare the time to get it working (piece of cake with an Application Server such as GlassFish or JBoss, and easy with Spring). If you annotate your business method with #TransactionAttribute(REQUIRED) (it can even be set to be done as default) and it calls the two DAO methods you will get exactly what you want: everything gets committed at once or rolled back over an Exception.
This solution is about as loosely coupled as it gets.
The others are correct in that they take in to account what are common practice currently.
But that doesn't really help you with your current practice.
What you should do is create two new DAO methods. Such as CreateGlobalSession and CommitGlobalSession.
What these do is the same thing as your current create and commit routines.
The difference is that they set a "global" session variable (most likely best done with a ThreadLocal). Then you change the current routines so that they check if this global session already exists. If your create detects the global session, then simply return it. If your commit detects the global session, then it does nothing.
Now when you want to use it you do this:
try {
dao.createGlobalSession();
beanA.save();
beanb.save();
Dao.commitGlobalSession();
} finally {
dao.rollbackGlobalSession();
}
Make sure you wrap the process in a try block so that you can reset your global session if there's an error.
While the other techniques are considered best practice and ideally you could one day evolve to something like that, this will get you over the hump with little more than 3 new methods and changing two existing methods. After that the rest of your code stays the same.
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();
}
}