2012-03-08 3 views
2

Я хочу сопоставить два класса с отношением manyToOne/oneToMay с Apache OpenJPA 2.2.0. Один Classe имеет первичный ключ из двух атрибутов:JPA Карта 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

Когда я меняю команду в строку (имя), то я получаю еще одно исключение: исключение в потоке «главный» org.apache.openjpa.persistence .ArgumentException: тип поля «model.Player.team» не поддерживается заявленной стратегией сохранения «ManyToOne». Выберите другую стратегию. – veote

+0

Нет, вам не нужно менять тип, просто имя переменной должно совпадать. Итак, название команды в обоих классах Team и PlayerId. Кроме того, я не думаю, что вам нужно использовать @Id, если вы уже используете @ IdClass –

+0

Когда я меняю частную команду команды на личное имя команды, я получаю те же исключения ... Когда я удаляю аннотацию @Id, тогда я получить исключение, что я не объявлял какой-либо первичный ключ ... – veote

0

У меня была та же проблема, которая была ранее, и нашел свое решение здесь: https://wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/DerivedIdentifiers

Вы should't добавить объект в вашем idClass, но идентификатор вашего лица. Так что попробуйте

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

    ... 
} 
Смежные вопросы