问题描述
我想用Apache OpenJPA 2.2.0映射两个具有manyToOne/oneToMay关系的类.一类具有两个属性的主键:
I want to map two classes with a manyToOne /oneToMay relation with Apache OpenJPA 2.2.0.One classe has a primary key of two attributes:
@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;
}
}
因此,当我与团队创建新的Player时,我会得到以下例外情况:
So When I create a new Player with a team I get the follwing exceptions:
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)
我知道为什么得到这个,但是我无法解决.有人可以帮我吗?
I know why I get this, but I cant fix it.Can someone help me?
当我使用不带IdClass的生成的主键(也许是长ID)时,没有问题.但是我需要IdClass.
There is no problem, when I use a generated primary key (maybe long id) without IdClass.But I need the IdClass.
最好的问候投票
推荐答案
我的猜测:
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/zh-CN/html_single/
It's easier to use @EmbeddedId in this case I think. See http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/
该站点上的简单示例:
@Entity
class User {
@EmbeddedId
@AttributeOverride(name="firstName", column=@Column(name="fld_firstname")
UserId id;
Integer age;
}
@Embeddable
class UserId implements Serializable {
String firstName;
String lastName;
}
我也将从TeamId类中删除Team,乍一看这似乎不是一个合理的设计选择.
I would also remove Team from the class PlayerId, that doesn't seem a logical design choice at first sight.
这篇关于JPA将IdClass与ManyToOne关系映射-persistence.ArgumentException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!