【发布时间】:2012-05-29 20:48:50
【问题描述】:
我正在尝试使用 JPA2 映射以下数据库结构:
ASSET
ID: assetId
...
PARTY
ID: partyId
...
PARTYASSET
ID: partyId
ID: assetId
ID: relationshipType
PARTYASSET 的主键是 PARTY 和 ASSET 的外键和一个附加列的组合:relationshipType。
由于列 relationshipType,我不能使用 @ManyToMany 注释,我必须使用 @ManyToOne 和 @OneToMany,如以下链接所述: http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany
我尝试了以下指南,但没有帮助: http://www.kawoolutions.com/Technology/JPA,_Hibernate,_and_Co./JPA_Composite_Key_Variants#JPA_2.0_@IdClass
你能帮帮我吗?
我尝试了以下方法: (继承是为了其他目的)
党课
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("PARTY")
public class Party implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long partyId;
@OneToMany(mappedBy = "party")
private Set<PartyAsset> partyAsset;
...
}
资产类别
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("ASSET")
public class Asset implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long assetid;
@OneToMany(mappedBy = "asset")
private Set<PartyAsset> partyAsset;
...
}
使用@IdClass:
PartyAsset 类
@Entity
@IdClass(PartyAssetPK.class)
public class PartyAsset implements Serializable {
private static final long serialVersionUID = 1L;
public static enum RelationshipType {
OWNER, TENANT, SECONDARY_CONTACT, SUPPLIER
}
@Id
@Enumerated(EnumType.STRING)
private RelationshipType relationshipType;
@Id
@ManyToOne
@JoinColumn(name="partyId")
private Party party;
@Id
@ManyToOne
@JoinColumn(name="assetId")
private Asset asset;
...
}
PartyAssetPK 类
public class PartyAssetPK implements Serializable {
private static final long serialVersionUID = 1L;
private Long partyId;
private Long assetId;
private PartyAsset.RelationshipType relationshipType;
}
上面的代码抛出异常:
在实体 PartyAsset 中找不到 @IdClass 的属性:assetId
@IdClass 的替代方案
PartyAsset 类
@Entity
@IdClass(PartyAssetPK.class)
public class PartyAsset implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long partyId;
@Id
private Long assetId;
public static enum RelationshipType {
OWNER, TENANT, SECONDARY_CONTACT, SUPPLIER
}
@Id
@Enumerated(EnumType.STRING)
private RelationshipType relationshipType;
@ManyToOne
@JoinColumn(name="partyId")
@MapsId("partyId")
private Party party;
@ManyToOne
@JoinColumn(name="assetId")
@MapsId("assetId")
private Asset asset;
}
这会引发异常:
找不到超类型
使用@EmbeddedId
PartyAsset 类
@Entity
public class PartyAsset implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
public PartyAssetPK id;
public static enum RelationshipType {
OWNER, TENANT, SECONDARY_CONTACT, SUPPLIER
}
@MapsId("relationshipType")
@Enumerated(EnumType.STRING)
private RelationshipType relationshipType;
@ManyToOne
@JoinColumn(name="partyId")
@MapsId("partyId")
private Party party;
@ManyToOne
@JoinColumn(name="assetId")
@MapsId("assetId")
private Asset asset;
}
PartyAssetPK 类
@Embeddable
public class PartyAssetPK implements Serializable {
private static final long serialVersionUID = 1L;
private Long partyId;
private Long assetId;
private PartyAsset.RelationshipType relationshipType;
}
这会引发异常;
引起:org.springframework.beans.factory.BeanCreationException: 创建名称为“entityManagerFactoryBean”的bean时出错 班级 com.ardan1.propertymanagement.test.config.TestApplicationContext: 调用 init 方法失败;嵌套异常是 java.lang.NullPointerException 引起: java.util.Hashtable.put 处的 java.lang.NullPointerException(未知 源)在 java.util.Properties.setProperty(未知源)在 org.hibernate.cfg.annotations.SimpleValueBinder.setType(SimpleValueBinder.java:227) 在 org.hibernate.cfg.annotations.PropertyBinder.makePropertyAndValue(PropertyBinder.java:188) 在 org.hibernate.cfg.annotations.PropertyBinder.makePropertyValueAndBind(PropertyBinder.java:203) 在 org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2013) 在 org.hibernate.cfg.AnnotationBinder.fillComponent(AnnotationBinder.java:2385)
我有以下库(使用 Maven):
<hibernate.version>4.1.2</hibernate.version>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.0.3.RELEASE</version>
</dependency>
【问题讨论】:
-
这回避了问题,但您为什么不简单地为 PartyAsset 实体使用一个技术性的、非复合的、自动生成的 ID。这会容易得多!
-
可嵌入情况下的异常是否是堆栈跟踪中最底层的部分?如果没有,请给出stacktrace中最底层的东西
-
JB Nizet,感谢您的评论。使用自动生成 ID 的简单性您可能是对的,但是,我想坚持使用数据库结构。
-
JMelnik,是的,堆栈跟踪是我控制台中出现的最后一件事。
-
您可以将 PartyAsset 映射为组件(可嵌入),将集合映射为组件集合
标签: spring hibernate jpa jpa-2.0 spring-data-jpa