| |
|
|
| Change By: |
Ma |
| Environment: |
Hibernate 5.1.0 Final,Spring 4.2.5 |
|
{code:java} // Some comments here public String getFoo() { return foo; } {code} I have a problem to lock some row when I use a projection to get entity count ,and occur nullPointerException ! I stepped through the hibernate code in the debugger. This is a BUG!!There is a long BUG!!
Hibernate version:5.1.0.Final
Code between sessionFactory.openSession() and session.close():
/***********************CODE*****************************/ {code:java} Criteria criteria = getSession().createCriteria(TbGenerateRecord.class); criteria.setLockMode(LockMode.PESSIMISTIC_WRITE); criteria.setProjection(Projections.rowCount()).uniqueResult(); {code} /***********************CODE*****************************/
soon after,I stepped through the hibernate code in the debugger. The NullPointerException in CriteriaLoader.applyLocks happens because its local "entityAliases" array is null; that array is null because the "aliases" field (defined in OuterJoinLoader) is null. So the question is, where did (or should) OuterJoinLoader.aliases come from? Well, it comes from a method called initFromWalker(JoinWalker walker), which calls walker.getAliases().
So now the question is, what's up with this JoinWalker? In this case, it is a CriteriaJoinWalker, which extends AbstractEntityJoinWalker.
Where, then, does (or should) JoinWalker.aliases get initalized? It happens in a method called initPersisters. This method, in turn, is called by the AbstractEntityJoinWalker.initAll method.
Why isn't CriteriaJoinWalker calling that initAll method? Here's the relevant code in the CriteriaJoinWalker constructor:
/***********************CODE*****************************/ {code:java} if ( translator.hasProjection() ) { initProjection( translator.getSelect(), translator.getWhereCondition(), translator.getOrderBy(), translator.getGroupBy(), LockOptions.NONE );
resultTypes = translator.getProjectedTypes();
userAliases = translator.getProjectedAliases();
includeInResultRow = new boolean[resultTypes.length];
Arrays.fill( includeInResultRow, true );
} else {
initAll( translator.getWhereCondition(), translator.getOrderBy(), LockOptions.NONE );
// root entity comes last userAliasList.add( criteria.getAlias() );
//root entity comes *last* resultTypeList.add( translator.getResultType( criteria ) );
includeInResultRowList.add( true );
userAliases = ArrayHelper.toStringArray( userAliasList );
resultTypes = ArrayHelper.toTypeArray( resultTypeList );
includeInResultRow = ArrayHelper.toBooleanArray( includeInResultRowList ); }
{code } /***********************CODE*****************************/ So, when there's a projection, we don't call the initAll method, and so the aliases field is never initialized. NPE is not a helpful error message.
If there are solutions, please contact me:2245089166@qq.com
Full stack trace of any exception that occurs: java.lang.NullPointerException at org.hibernate.loader.criteria.CriteriaLoader.applyLocks(CriteriaLoader.java:237) at org.hibernate.loader.Loader.preprocessSQL(Loader.java:234) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1894) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1874) at org.hibernate.loader.Loader.doQuery(Loader.java:919) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) at org.hibernate.loader.Loader.doList(Loader.java:2610) at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2452) at org.hibernate.loader.Loader.list(Loader.java:2414) at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:109) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1787) at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:363) at org.hibernate.internal.CriteriaImpl.uniqueResult(CriteriaImpl.java:385) at net.yasion.common.utils.HibernateUtils.countByCriteria(HibernateUtils.java:274) at net.yasion.common.dao.impl.BaseDAOImpl.sourceListByCriteria(BaseDAOImpl.java:574) at net.yasion.common.dao.impl.BaseDAOImpl.listByCriteria(BaseDAOImpl.java:484) at net.yasion.shortlink.service.impl.LinkServiceImpl.shortLink(LinkServiceImpl.java:126) |
|
|
|
| |
|