我是JPA的新手,我花了最近4天的时间试图弄清楚为什么* & ^!@我的查询不断爆炸。看起来问题似乎与我正在使用的变量的名称有关。请参阅下面的我的实体和测试课程。我很抱歉,但我尽量简化它。与实体变量名称相关的JPA/Hibernate查询失败
@Entity
public class MyEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
@Column(length = 50)
private String name;
@ManyToOne
private MyEntity myEntity;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "myEnt", fetch = FetchType.EAGER)
@MapKey(name = "typeName")
private Map<String, ContainedEntity> ecConfigs;
public MyEntity() {
}
public MyEntity(String name, MyEntity myEntity) {
this.name = name;
this.myEntity = myEntity;
}
public MyEntity(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Map<String, ContainedEntity> getEcConfigs() {
return ecConfigs;
}
public void setEcConfigs(Map<String, ContainedEntity> ecConfigs) {
this.ecConfigs = ecConfigs;
}
public MyEntity getMyEntity() {
return myEntity;
}
public void setMyEntity(MyEntity myEntity) {
this.myEntity = myEntity;
}
public String toString() {
return name + " -- " + myEntity;
}
}
@IdClass(ContainedEntityPK.class)
@Entity
public class ContainedEntity {
@Id
private String typeName;
@Id
private MyEntity myEnt;
@Column(length = 255)
private String ceName;
public ContainedEntity() {
}
public ContainedEntity(String typeName, String ceName) {
super();
this.typeName = typeName;
this.ceName = ceName;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public MyEntity getMyEnt() {
return myEnt;
}
public void setMyEnt(MyEntity myEnt) {
this.myEnt = myEnt;
}
public String getCeName() {
return ceName;
}
public void setCeName(String ceName) {
this.ceName = ceName;
}
}
public class ContainedEntityPK implements Serializable{
private static final long serialVersionUID = -1714218588564578557L;
@Column(length = 255)
private String typeName;
@ManyToOne
private MyEntity myEnt;
public ContainedEntityPK() {
}
public ContainedEntityPK(String typeName, MyEntity myEnt) {
super();
this.typeName = typeName;
this.myEnt = myEnt;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String name) {
this.typeName = name;
}
public MyEntity getMyEnt() {
return myEnt;
}
public void setMyEnt(MyEntity myEnt) {
this.myEnt = myEnt;
}
public int hashCode() {
return (int) (typeName.hashCode() + myEnt.hashCode());
}
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (!(obj instanceof ContainedEntityPK))
return false;
ContainedEntityPK pk = (ContainedEntityPK) obj;
return pk.getMyEnt().equals(myEnt) && pk.typeName.equals(typeName);
}
}
public class Tester {
static EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPersistenceUnit");
/**
* @param args
*/
public static void main(String[] args) {
addEntities();
findEntity("aEntity");
findEntity("bEntity");
}
public static void addEntities() {
EntityManager em = emf.createEntityManager();
MyEntity aEntity = new MyEntity("aEntity");
MyEntity bEntity = new MyEntity("bEntity", aEntity);
em.getTransaction().begin();
em.persist(aEntity);
em.persist(bEntity);
em.getTransaction().commit();
em.close();
}
public static void findEntity(String name) {
EntityManager em = emf.createEntityManager();
TypedQuery<MyEntity> q = em.createQuery("SELECT M FROM MyEntity M WHERE M.name=:name", MyEntity.class);
q.setParameter("name", name);
System.out.println(q.getSingleResult());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="testPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>test.nocommit.MyEntity</class>
<class>test.nocommit.ContainedEntity</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@server:1521:instance"/>
<property name="javax.persistence.jdbc.user" value="user"/>
<property name="javax.persistence.jdbc.password" value="pass"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
当我运行先前的主类,它的行为如我所料,并得到下面的输出:
aEntity - 空
bEntity - aEntity - null
但是,如果我更改MyEntity.ecConfigs VA可变结构名称MyEntity.secConfigs和更改getter/setter方法给:
public Map<String, ContainedEntity> getSecConfigs() {
return secConfigs;
}
public void setSecConfigs(Map<String, ContainedEntity> secConfigs) {
this.secConfigs = secConfigs;
}
它上的Findentity( “bEntity”)炸毁;呼叫。我的输出是:
aEntity - 空
其次是例外:
Exception in thread "main" org.hibernate.AssertionFailure: null identifier
at org.hibernate.engine.spi.EntityKey.<init>(EntityKey.java:69)
at org.hibernate.internal.AbstractSessionImpl.generateEntityKey(AbstractSessionImpl.java:240)
at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:722)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:635)
at org.hibernate.loader.Loader.doQuery(Loader.java:856)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2058)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:82)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:72)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3697)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:439)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:420)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:204)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:251)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:148)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:954)
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:903)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:610)
at org.hibernate.type.EntityType.resolve(EntityType.java:438)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:150)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1006)
at org.hibernate.loader.Loader.doQuery(Loader.java:883)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doList(Loader.java:2463)
at org.hibernate.loader.Loader.doList(Loader.java:2449)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2279)
at org.hibernate.loader.Loader.list(Loader.java:2274)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1115)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:280)
at test.nocommit.Tester.findEntity(Tester.java:38)
at test.nocommit.Tester.main(Tester.java:17)
起初我在春天责备这一点,但我已经剥夺一切春天的权利,并仍然遇到的问题。
我的休眠版本调用自己4.0.1.Final
我在这里丢失了什么吗?是否有一些变量名称要求?我是否踩了一些保留字?我没有正确地指定某些东西吗?从我所知道的情况来看,可能与自引用实体以及复合主键有一些关系......我目前在我的隔间里感到困惑和哭泣。
在DataNucleus JPA(带有ecConfigs或secConfigs)上正常工作。我在任何地方都看不到保留字,除此之外,如果在RDBMS中有某个保留字,那么它可以很容易地通过JPA实现引用。请注意,您尚未在GeneratedValue中指定序列名称,因此需要添加(可能它简直错过了该帖子,但您确实拥有它)? – DataNucleus 2012-03-10 09:24:54
OP的错误报告:https://hibernate.atlassian.net/浏览/ HHH-7178 – Arjan 2015-01-02 15:43:56