我正在将现有的Hibernate项目从xml映射升级到注释。
我有一个与xml映射一起使用的简单示例,但是我的注释出现以下错误:
Exception in thread "main" java.lang.IllegalArgumentException: Provided id of the wrong type for class hib.StrategyRevision. Expected: class hib.StrategyRevisionPK, got class hib.StrategyRevision
at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:196)
at hib.Main.main(Main.java:34)
Caused by: org.hibernate.TypeMismatchException: Provided id of the wrong type for class hib.StrategyRevision. Expected: class hib.StrategyRevisionPK, got class hib.StrategyRevision
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:109)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:182)
... 1 more
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="hib">
<class name="PortfolioRevision" table="PortfolioRevisions">
<id name="revisionId" column="RevisionId" unsaved-value="any">
<generator class="identity"/>
</id>
</class>
<class name="Strategy" table="PortfolioStrategies">
<id name="id" column="StrategyId" unsaved-value="any">
<generator class="identity"/>
</id>
</class>
<class name="StrategyRevision" table="StrategyRevisions">
<composite-id>
<key-many-to-one name="portfolioRevision" class="PortfolioRevision" column="PortfolioRevisionId"/>
<key-many-to-one name="strategy" class="Strategy" column="StrategyId"/>
</composite-id>
</class>
</hibernate-mapping>
这是我的注释课程:
@Entity
@Table(name="PortfolioRevisions")
public class PortfolioRevision {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int revisionId;
public int getRevisionId() {
return revisionId;
}
public void setRevisionId(int revisionId) {
this.revisionId = revisionId;
}
}
@Entity
@Table(name="PortfolioStrategies")
public class Strategy {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="StrategyId")
private int id;
public Strategy() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
@Entity
@Table(name="StrategyRevisions")
@AssociationOverrides({
@AssociationOverride(name="pk.portfolioRevision", joinColumns={@JoinColumn(name="PortfolioRevisionId")}),
@AssociationOverride(name="pk.strategy", joinColumns={@JoinColumn(name="StrategyId")})
})
public class StrategyRevision implements java.io.Serializable {
private static final long serialVersionUID = -8792535918405463902L;
@EmbeddedId
private StrategyRevisionPK pk = new StrategyRevisionPK();
@Transient
public Strategy getStrategy() {
return pk.getStrategy();
}
public void setStrategy(Strategy strategy) {
this.pk.setStrategy(strategy);
}
@Transient
public PortfolioRevision getPortfolioRevision() {
return pk.getPortfolioRevision();
}
public void setPortfolioRevision(PortfolioRevision portfolioRevision) {
this.pk.setPortfolioRevision(portfolioRevision);
}
}
@Embeddable
public class StrategyRevisionPK implements java.io.Serializable {
private static final long serialVersionUID = 8058688937408537945L;
@ManyToOne
private PortfolioRevision portfolioRevision;
@ManyToOne
private Strategy strategy;
public StrategyRevisionPK() {}
public PortfolioRevision getPortfolioRevision() {
return portfolioRevision;
}
public void setPortfolioRevision(PortfolioRevision portfolioRevision) {
this.portfolioRevision = portfolioRevision;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
// override & equals...
}
查找失败的主要方法:
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("list");
em = factory.createEntityManager();
em.getTransaction().begin();
PortfolioRevision portfolioRevision = new PortfolioRevision();
em.persist(portfolioRevision);
Strategy strategy = new Strategy();
em.persist(strategy);
StrategyRevision strategyRevision = new StrategyRevision();
strategyRevision.setPortfolioRevision(portfolioRevision);
strategyRevision.setStrategy(strategy);
em.persist(strategyRevision);
// TEST
StrategyRevision strategyRevision2 = new StrategyRevision();
strategyRevision2.setStrategy(strategy);
strategyRevision2.setPortfolioRevision(portfolioRevision);
strategyRevision2 = em.find(StrategyRevision.class, strategyRevision);
em.getTransaction().commit();
}
如果有人可以纠正我的注释中的错误,那么他们的工作方式与现有的xml映射相同,我将负债。我正在使用Hibernate 3.3.1.GA 感谢。
答案 0 :(得分:1)
XML文件是一个hibernate映射文件,并没有将1:1映射到JPA - 您的映射失败,因为您已将StrategyRevisionPK指定为ID,但正在传递StrategyRevision实例。如果要纯粹在JPA中映射,则必须对如何使用内容进行更改。您可以保留原始模型(我假设包装pk实例的getStrategy方法是更改),只需将StrategyRevisionPK添加为PKClass,而不是将其作为可嵌入的实体放入实体中。
类似的东西:
@IdClass(StrategyRevisionPK.class)
public class StrategyRevision implements java.io.Serializable {
@Id
Strategy strategy;
@Id
PortfolioRevision portfolioRevision;
}
public class StrategyRevisionPK implements java.io.Serializable {
public int strategy;
public int portfolioRevision;
}
重要的部分是IDClass中的属性/字段必须与Entity类中标记为@Id的属性/字段的名称匹配,但具有在引用实体中使用的类型。然后,您可以将StrategyRevisionPK实例传递给JPA查找操作,否则不会使用它们。