Using JPA Metamodel in criteria API throws NPE first time - jpa

I am using JPA Criteria API with JPA meta model.
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<T> criteria = cb.createQuery(User.class);
final Root<T> root = criteria.from(User.class);
criteria.select(root).where(cb.equal(root.get(User_.username), value));
return em.createQuery(criteria).getResultList();
here the problem is root.get method throws NPE first time after the server starts (i.e first execution after server start), but the same code works fine from second execution onwards. It doesn't matter when the first execution executed after server started. It may be executed after few seconds or after few minutes.
Following is the exception thrown:
java.lang.NullPointerException: null
at org.apache.openjpa.persistence.criteria.PathImpl.get(PathImpl.java:245) ~[openjpa-2.4.2.jar:2.4.2]
If you look at the source code of PathImpl.get
public <Y> Path<Y> get(SingularAttribute<? super X, Y> attr) {
if (getType() != attr.getDeclaringType()) {
attr = (SingularAttribute)((ManagedType)getType()).getAttribute(attr.getName());
}
return new PathImpl<X,Y>(this, (Members.SingularAttributeImpl<? super X, Y>)attr, attr.getJavaType());
}
it access attr.getDeclaringType()
If I look at the JPA meta model which is auto generated it looks as follows:
public class User_ {
public static volatile SingularAttribute<User,String> username;
...
}
username is definitely null, however the code works well except first time.
It appears during runtime JPA set value to User_.username.
so question is how do prevent throwing NPE first time!
Using TomEE 7.0.4

Related

#Query in JPA throwing null pointer exception

I am getting nullPointerException from my custom jpa method findShiftNameById() in my shift planner project(github link below). I have used #Query annotation inside ShiftDetailsRepo Interface to implement the method. Please check and let me know what could be causing this. I tried by removing nativeQuery parameter but that gives shift_details not mapped error.I tried by changing datatypes between int and long and also by changing sd.shiftName to sd.shift_name(as per the column name that is available in my actual database) but still same nullPointerException error is coming.
Github link-https://github.com/Anupam5713/shiftPlannerAPI
The method is being called in the ShiftPlanService Class inside the service package
Is there something wrong in my query?
#Query(value = "select sd.shiftName from shift_details sd where sd.shiftId=:shiftId",nativeQuery=true)
public String findShiftNameById(#Param("shiftId") int shiftId);
The following is the cause of NPE. The call to sdr is done before the dependencies are wired.
#Service
public class ShiftPlanService {
#Autowired
ShiftDetailsRepo sdr;
String S1 = sdr.findShiftNameById(1);
String S2 = sdr.findShiftNameById(2);
Move these initializations to a #PostConstruct method.
Example
#PostConstruct
public void initDetails() {
S1 = sdr.findShiftNameById(1);
S2 = sdr.findShiftNameById(2);
}

JBOSS Arquillian : How to force database to throw exception while running the aquillian test?

I am implementing a feature where if there is any exception while writing data into DB, we should retry it for 5 times before failing. I have implemented the feature but not able to test it using arquillian test.
We are using JPA and Versant as database. Till now, I am debbuging the the arquillian test and once my flow reaches DB handler code, I am stopping the database. But this is worst way of testing.
Do you have any suggestion how to achieve the same ?
With JPA in mind, the easiest way is to add method to your data access layer, with which you are able to run native queries. Then you run query against nonexisting table or something similar. So in my DAO utilities I found method like this:
public List findByNativeQuery(String nativeQuery, Map<String, Object> args) {
try{
final EntityManager em = getEntityManager();
final Query query = em.createNativeQuery(nativeQuery);
if (args!=null && args.entrySet().size()>0) {
final Iterator it = args.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry pairs = (Map.Entry)it.next();
query.setParameter(pairs.getKey().toString(), pairs.getValue());
}
}
return query.getResultList();
}
catch (RuntimeException e) {
// throw some new Exception(e.getMessage()); // the best is to throw checked exception
}
}
Native solutions
There is the old trick by dividing by zero in the database. At the time of selection you could try:
select 1/0 from dual;
Insertion time (you need a table):
insert into test_table (test_number_field) values (1/0);
pure JPA solution
You can try to utilize the #Version annotation and decrement it to throw OptimisticLockException. This is not thrown in the database, but in the Java layer, but fullfills your need.
Those all will result in DB fail.

EclipseLink JPA Dynamic model and Criteria Query

i like to create a (crtieria-) query against a dynamic model but i always get the exception
No [EntityType] was found for the key class [demo.DynamicResult] in the Metamodel
at the last line
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Tuple> query = criteriaBuilder.createTupleQuery();
DynamicHelper helper = new DynamicHelper(JpaHelper.getServerSession(emf));
Class<? extends DynamicEntity> rootclass = helper.getType("demo.DynamicResult").getJavaClass();
query.from(rootclass);
The DynamicResult gets generated with following code
ServerSession serverSession = JpaHelper.getEntityManager(entityManager).getServerSession();
DynamicClassLoader dcl = DynamicClassLoader.lookup(serverSession);
JPADynamicHelper jpaDynamicHelper = new JPADynamicHelper(entityManager);
Class<?> dynamicResult = dcl.createDynamicClass("demo.DynamicResult");
JPADynamicTypeBuilder dynamicResultBuilder = new JPADynamicTypeBuilder(dynamicResult, null, "DynamicResult");
dynamicResultBuilder.addDirectMapping("id", String.class, "id");
//Some more addDirectMappings ....
dynamicResultBuilder.setPrimaryKeyFields("id");
type = dynamicResultBuilder.getType();
jpaDynamicHelper.addTypes(false, false, type);
What did I missed ?
Is this kind of query possible at all ?
Regards
You may be hitting https://bugs.eclipse.org/bugs/show_bug.cgi?id=429760 bug. There was a problem with copying newly created dynamic entity metadata into current session.
Check this bug and attached diffs. jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/dynamic/simple/SimpleQueryTestSuite.java test suite contains test which does similar thing - creates dynamic entity and runs JPQL query against it within the same transaction (UnitOfWork).
I would try latest 2.7.0 or 2.6.1 (do not use .WAS) build from https://www.eclipse.org/eclipselink/downloads/nightly.php to see if it works fine for you.

Using EF with stored procedure and getting error as New transaction is not allowed because there are other threads running in the session

In Entity framework, I have implemented generic repository and unit of work pattern.
Below is related stuff from unit of work:
public IRepository<TEntity, TKey> GetRepository<TEntity, TKey>() where TEntity : class
{
if (_repositories == null)
{
_repositories = new Dictionary<string, object>();
}
string key = String.Format("{0}|{1}", typeof(TEntity).Name, typeof(TKey).Name);
if (_repositories.ContainsKey(key))
{
return (IRepository<TEntity, TKey>)_repositories[key];
}
Type repositoryType = typeof(Repository<TEntity, TKey>);
_repositories.Add(key, Activator.CreateInstance(repositoryType, _dataContext));
return (IRepository<TEntity, TKey>)_repositories[key];
}
From Manager layer, entity framework is call as below:
IRepository<tablenameEntity int> _tableEntityRepository = _unitOfWork.GetRepository<tablenameEntity, int>();
Error is as follow:
An error occurred while starting a transaction on the provider connection. See the inner exception for details.
{"New transaction is not allowed because there are other threads running in the session."}.
Actually, I just did as below,
remove stored procedure and function from model browser and added procedure and function again.
run custom tool on edmx file.
It just work out.
I am not sure, what was the issue. did that before also, but it was not work.. now, it works and not produce after that.
Thanks

Why transaction can't commit in a self-invoked ejb method with #REQUIRES_NEW Annotation

First I want to explain my self-invoked ejb method in this situation. I have a stateful session bean with a method which starts a new transaction (Annotated by #REQUIRES_NEW). To invoke this method inside the bean itself and make the annotation effective, I use SessionContext#getBusinessObject() to achieve the effect of #EJB (#EJB here causes stackoverflow?!). My code is shown below:
#Stateful
#Local
public class TransactionTest implements ITransactionTest {
#PersistenceContext(unitName="Table",Type=PersistenceContextType.EXTENDED)
private EntityManager manager;
#Resource
SessionContext sc;
ITransactionTest me;
#PostConstruct
public void init(){
me = this.sc.getBusinessObject(ITransactionTest.class);
}
public void generateRecord(int i) throws RuntimeException{
Record record = new Record();
record.setId(i+"");
record.status(1);
manager.persist(record);
manager.flush(); //If not flush, result is correct. Why?
me.updateRecord(i);
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void updateRecord(int i) throws RuntimeException{
try {
Record record = manager.find(Record.class, i+"");
record.setStatus(2);
manager.flush();
} catch(Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
}
While,generateRecord() runs properly. The console shows it executes 'insert' and 'update' HQL without any exception (I use Hibernate as JPA provider). However, the 'update' result doesn't appear in the database. Why? Does updateRecord() commit correctly?
Also, I try it in two altenative ways: First is invoking generateRecord() (it will no longer invoke updateRecord()) and updateRecord() consecutively in another bean. It can give me the right result.
The second is removing the first flush(). Then both 'insert' and 'update' HQL will be executed at the second flush(). This method can also produce right result.
My program is running under JBOSS 6.1.0-Final and database is Oracle.
Best Regards,
Kajelas