2012-03-08 82 views
2

我想用Apache OpenJPA 2.2.0映射兩個具有manyToOne/oneToMay關係的類。 其中一個班有兩個屬性的主鍵:JPA Map ManyToOne與IdClass的關係 - persistence.ArgumentException

@Entity(name = "Player") 
@IdClass(PlayerId.class) 
public class Player { 
    @Id 
    private String nickname; 
    @Id 
    @ManyToOne(cascade = CascadeType.PERSIST) 
    @JoinColumn(name = "team_id") 
    private Team team; 

    public Player() { 

    } 

    public String getNickname() { 
     return nickname; 
    } 

    public void setNickname(String nickname) { 
     this.nickname = nickname; 
    } 

    public Team getTeam() { 
     return team; 
    } 

    public void setTeam(Team team) { 
     this.team = team; 
    } 

} 

public class PlayerId { 
    private String nickname; 
    private Team team; 

    public PlayerId() { 
    } 

    public String getNickname() { 
     return nickname; 
    } 

    public void setNickname(String nickname) { 
     this.nickname = nickname; 
    } 

    public Team getTeam() { 
     return team; 
    } 

    public void setTeam(Team team) { 
     this.team = team; 
    } 

    @Override 
    public boolean equals(Object o) { 
     return ((o instanceof PlayerId) && 
       this.nickname == ((PlayerId)o).getNickname() && 
       this.team == ((PlayerId) o).getTeam()); 
    } 

    public int hashCode() { 
     return nickname.hashCode() + team.hashCode(); 
    } 
} 

@Entity(name = "Team") 
public class Team { 
    @Id 
    private String name; 

    @OneToMany(mappedBy = "team", targetEntity = Player.class, fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) 
    private List<Player> players; 

    public Team() { 

    } 

    public List<Player> getPlayers() { 
     return players; 
    } 

    public void setPlayers(List<Player> p) { 
     players = p; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

所以,當我創建一個團隊,我得到了follwing例外一個新的播放器:

Exception in thread "main" <openjpa-2.2.0-r422266:1244990 fatal user error> org.apache.openjpa.persistence.ArgumentException: Errors encountered while resolving metadata. See nested exceptions for details. 
    at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:668) 
    at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:411) 
    at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:384) 
    at org.apache.openjpa.meta.MetaDataRepository.resolveMeta(MetaDataRepository.java:714) 
    at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:643) 
    at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:411) 
    at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:384) 
    at org.apache.openjpa.jdbc.meta.MappingRepository.getMapping(MappingRepository.java:355) 
    at org.apache.openjpa.jdbc.meta.MappingTool.getMapping(MappingTool.java:682) 
    at org.apache.openjpa.jdbc.meta.MappingTool.buildSchema(MappingTool.java:754) 
    at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:652) 
    at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:154) 
    at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:164) 
    at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newBrokerImpl(JDBCBrokerFactory.java:122) 
    at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:209) 
    at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156) 
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227) 
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:154) 
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:60) 
    at main.Main.main(Main.java:27) 
Caused by: <openjpa-2.2.0-r422266:1244990 fatal user error> org.apache.openjpa.persistence.ArgumentException: The id class specified by type "class model.Player" does not match the primary key fields of the class. Make sure your identity class has the same primary keys as your persistent type, including pk field types. Mismatched property: "team" 
    at org.apache.openjpa.meta.ClassMetaData.validateAppIdClassPKs(ClassMetaData.java:2216) 
    at org.apache.openjpa.meta.ClassMetaData.validateAppIdClass(ClassMetaData.java:2090) 
    at org.apache.openjpa.meta.ClassMetaData.validateIdentity(ClassMetaData.java:2026) 
    at org.apache.openjpa.meta.ClassMetaData.validateMeta(ClassMetaData.java:1938) 
    at org.apache.openjpa.meta.ClassMetaData.resolve(ClassMetaData.java:1799) 
    at org.apache.openjpa.meta.MetaDataRepository.processBuffer(MetaDataRepository.java:822) 
    at org.apache.openjpa.meta.MetaDataRepository.resolveMeta(MetaDataRepository.java:719) 
    at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:643) 
    ... 19 more 
NestedThrowables: 
<openjpa-2.2.0-r422266:1244990 fatal user error> org.apache.openjpa.persistence.ArgumentException: Attempt to map "model.Player.team" failed: the owning entity is not mapped. 
    at org.apache.openjpa.jdbc.meta.MappingInfo.assertTable(MappingInfo.java:628) 
    at org.apache.openjpa.jdbc.meta.MappingInfo.createForeignKey(MappingInfo.java:1079) 
    at org.apache.openjpa.jdbc.meta.ValueMappingInfo.getTypeJoin(ValueMappingInfo.java:115) 
    at org.apache.openjpa.jdbc.meta.ValueMappingInfo.getTypeJoin(ValueMappingInfo.java:92) 
    at org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.map(RelationFieldStrategy.java:167) 
    at org.apache.openjpa.jdbc.meta.FieldMapping.setStrategy(FieldMapping.java:146) 
    at org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(RuntimeStrategyInstaller.java:82) 
    at org.apache.openjpa.jdbc.meta.FieldMapping.resolveMapping(FieldMapping.java:496) 
    at org.apache.openjpa.jdbc.meta.FieldMapping.resolve(FieldMapping.java:461) 
    at org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.map(RelationToManyInverseKeyFieldStrategy.java:135) 
    at org.apache.openjpa.jdbc.meta.strats.RelationCollectionInverseKeyFieldStrategy.map(RelationCollectionInverseKeyFieldStrategy.java:95) 
    at org.apache.openjpa.jdbc.meta.FieldMapping.setStrategy(FieldMapping.java:146) 
    at org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(RuntimeStrategyInstaller.java:82) 
    at org.apache.openjpa.jdbc.meta.FieldMapping.resolveMapping(FieldMapping.java:496) 
    at org.apache.openjpa.jdbc.meta.FieldMapping.resolve(FieldMapping.java:461) 
    at org.apache.openjpa.jdbc.meta.ClassMapping.resolveMapping(ClassMapping.java:854) 
    at org.apache.openjpa.meta.ClassMetaData.resolve(ClassMetaData.java:1802) 
    at org.apache.openjpa.meta.MetaDataRepository.processBuffer(MetaDataRepository.java:822) 
    at org.apache.openjpa.meta.MetaDataRepository.resolveMapping(MetaDataRepository.java:777) 
    at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:657) 
    at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:411) 
    at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:384) 
    at org.apache.openjpa.meta.MetaDataRepository.resolveMeta(MetaDataRepository.java:714) 
    at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:643) 
    at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:411) 
    at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:384) 
    at org.apache.openjpa.jdbc.meta.MappingRepository.getMapping(MappingRepository.java:355) 
    at org.apache.openjpa.jdbc.meta.MappingTool.getMapping(MappingTool.java:682) 
    at org.apache.openjpa.jdbc.meta.MappingTool.buildSchema(MappingTool.java:754) 
    at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:652) 
    at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:154) 
    at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:164) 
    at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newBrokerImpl(JDBCBrokerFactory.java:122) 
    at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:209) 
    at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156) 
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227) 
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:154) 
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:60) 
    at main.Main.main(Main.java:27) 

我知道爲什麼我得到這個,但我不能修復它。 有人可以幫我嗎?

沒有問題,當我使用生成的主鍵(也許長ID)沒有IdClass。 但我需要IdClass。

問候 Veote

回答

1

我的猜測:

public class PlayerId { 
    private String nickname; 
    private Team team; -> this should be "name" to match the Id in the class Team. 

... 

} 

它更容易在這種情況下,我認爲使用@EmbeddedId。見http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/

的簡單的例子從網站:

@Entity 
class User { 
    @EmbeddedId 
    @AttributeOverride(name="firstName", [email protected](name="fld_firstname") 
    UserId id; 

    Integer age; 
} 

@Embeddable 
class UserId implements Serializable { 
    String firstName; 
    String lastName; 
} 

我也從類PlayerId,這似乎不是一個合理的設計選擇一見傾心刪除團隊。

+0

當我改變球隊爲String(名稱),然後我得到另一個異常:異常線程 「main」 org.apache.openjpa.persistence .ArgumentException:聲明的持久性策略「ManyToOne」不支持字段「model.Player.team」的類型。請選擇不同的策略。 – veote 2012-03-08 13:38:51

+0

不,您不必更改類型,只需要變量名稱必須匹配。所以Team和PlayerId都是Team名稱。 另外,我不認爲你必須使用@Id,如果你已經使用@ IdClass – 2012-03-08 13:43:45

+0

當我更改私人團隊團隊私人團隊名稱我得到相同的例外...當我刪除@ID註釋然後我得到異常,我沒有聲明任何主鍵... – veote 2012-03-08 13:52:16