2016-03-01 46 views
0

我正在將現有的Hibernate項目從xml映射升級到註釋。HIbernate提供了錯誤類型的ID,預計PK得到了實體

我有一個簡單的例子,它與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... 
} 

從而未能就找不到Main方法:

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

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字段必須屬性的名稱相匹配/場標記爲@Id在實體類,但在使用的類型被引用的實體。然後您會將StrategyRevisionPK實例傳遞給JPA查找操作,否則不會使用它們。

+0

感謝您的幫助克里斯。我嘗試使用@IdClass並將填充的PK傳遞給find方法,但是我得到PropertyAccessException:無法通過hib.StrategyRevisionPK.portfolioRevision.I的反射設置器設置字段值我將繼續嘗試並找出我的錯誤 – user1810292

+0

是否可以只需將上述XMl映射轉換爲Hibernate註釋?理想情況下,我不想更改任何現有的代碼只是註釋它 – user1810292

+0

我得到它像你說的那樣工作,並傳遞一個填充PK而不是實體到find方法。感謝您的幫助,我現在可以用ID課程搞定。 – user1810292

相關問題