HIbernate提供了错误类型的id,预期PK得到实体

时间:2016-03-01 11:02:10

标签: hibernate jpa

我正在将现有的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

Tables 这是原始工作的xml映射文件(针对此问题进行了简化):

<?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 感谢。

1 个答案:

答案 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查找操作,否则不会使用它们。