The setup: @Entity @Table(name = "batch") @SequenceGenerator(name = "BatchGen", sequenceName = "seq_batch", allocationSize = 1) public class Batch implements Serializable { ... @ElementCollection @CollectionTable( name = "batch_node", //uniqueConstraints = @UniqueConstraint(columnNames = {"batch_id", "node_id"} ), //foreignKey = @ForeignKey, joinColumns = @JoinColumn(name = "batch_id", nullable = false)) @MapKeyJoinColumn(name = "node_id") private Map<Node, BatchNodeMetadata> batchNodeMetadata = new HashMap<>(); ... } @Entity @Table(name= "node") @SequenceGenerator(name="NodeGen", sequenceName="seq_node", allocationSize=1) public class Node implements Serializable { ... } @Embeddable public class BatchNodeMetadata implements Serializable { @Column(nullable = false) @Enumerated(EnumType.STRING) private NodeMigration migrering = NodeMigration.TOTAL; public NodeMigration getMigrering() { return migrering; } public void setMigrering(NodeMigration migrering) { this.migrering = migrering; } }
- Testcase
class Test {
@Test public void testGetNodesInBatch() { Node n = new Node(); n.setName("Test"); nodeDAO.create(n); Batch b = new Batch(); b.setName("Test"); b.getBatchNodeMetadata().put(n, new BatchNodeMetadata()); batchDAO.create(b); Collection<String> actual = batchDAO.getNodesInBatch(b); Assert.assertEquals(1, actual.size()); } } class Dao { public Collection<Node> getNodesInBatch(Batch batch) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Node> query = cb.createQuery(Node.class); Root<Batch> root = query.from(Batch.class); MapJoin<Batch, Node, BatchNodeMetadata> nodes = root.join(Batch_.batchNodeMetadata); query.select(nodes.key()); query.where(cb.equal(root, batch)); return em.createQuery(query).getResultList(); } }
- Output
Everything from the setup seems to be correct
Hibernate: create table batch (id integer not null, current_activity varchar(255), name varchar(255) not null, pretty_current_activity varchar(255), visas_utanför_fabriken boolean, primary key (id)) Hibernate: create table batch_node (batch_id integer not null, migrering varchar(255) not null, node_id integer not null, primary key (batch_id, node_id)) Hibernate: create table node (id integer not null, edgar_complexity varchar(255), long_name varchar(255), municipal_area varchar(255), "name" varchar(255) not null, primary key (id)) Hibernate: alter table batch add constraint UK_ea6wjj8co7qtkcek0at693sh5 unique (name) Hibernate: alter table node add constraint UK_fwigxdmj6bsrpcmhcgpmlsirh unique ("name") Hibernate: alter table batch_node add constraint FK_hp7ye0ce3g9xb2h9newetnar5 foreign key (node_id) references node Hibernate: alter table batch_node add constraint FK_cdi1tq0y36ylqqm4dbvghaxk foreign key (batch_id) references batch Hibernate: call next value for seq_node Hibernate: insert into node (edgar_complexity, long_name, municipal_area, "name", id) values (?, ?, ?, ?, ?) Hibernate: call next value for seq_batch Hibernate: insert into batch (current_activity, name, pretty_current_activity, visas_utanför_fabriken, id) values (?, ?, ?, ?, ?) Hibernate: insert into batch_node (batch_id, node_id, migrering) values (?, ?, ?)
- NPE when executing the criteria
java.lang.NullPointerException: null at org.hibernate.hql.internal.ast.HqlSqlWalker.lookupProperty(HqlSqlWalker.java:592) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.addrExpr(HqlSqlBaseWalker.java:4980) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1263) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4686) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.arithmeticExpr(HqlSqlBaseWalker.java:3215) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2382) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2194) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1476) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:573) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301) at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158) at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:131) at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:93) at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167) at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301) at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236) at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1800) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:568) at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:336) at org.hibernate.jpa.criteria.compile.CriteriaCompiler.compile(CriteriaCompiler.java:147) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:736) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:262) at com.sun.proxy.$Proxy47.createQuery(Unknown Source) at com.dbmodel.dao.BatchDAO.getNodesInBatchStr(BatchDAO.java:132) at com.dbmodel.dao.BatchDAO$$FastClassBySpringCGLIB$$b9d5b01c.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644) at com.dbmodel.dao.BatchDAO$$EnhancerBySpringCGLIB$$4e2a04ba.getNodesInBatchStr(<generated>) at com.dbmodel.dao.BatchDAOIT.testGetNodesInBatch(BatchDAOIT.java:79)
|