我正在尝试使用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;
...
}
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: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;
}
抛出异常:
找不到超类型
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(未知来源)at 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>
答案 0 :(得分:0)
我认为您可以使用@JoinColumn进行映射。以下代码使用Spring Data JPA。
BaseEntity.java
import java.io.Serializable;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.data.jpa.domain.AbstractPersistable;
public abstract class BaseEntity<PK extends Serializable> extends AbstractPersistable<PK> implements Serializable {
private static final long serialVersionUID = 201304010827L;
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
}
AssetEntity.java
@Entity
@Table(name = "tb_asset")
@AttributeOverride(name = "id", column = @Column(name = "AssetID"))
public class AssetEntity extends BaseEntity<Long> {
@Column(name = "desc")
private String desciption;
// getters and setters...
}
PartyEntity.java
@Entity
@Table(name = "tb_party")
@AttributeOverride(name = "id", column = @Column(name = "PartyID"))
public class PartyEntity extends BaseEntity<Long> {
private String party;
// Getters and setters.
}
要使用@JoinColumn和@Embeddable,我们有PartyAsset.java。
@Embeddable
public class PartyAssetKey implements Serializable {
@ManyToOne
@JoinColumn(name = "party_id", referencedColumnName = "id")
private PartyEntity partyEntity;
@ManyToOne
@JoinColumn(name = "asset_id", referencedColumnName = "id")
private AssetEntity assetEntity;
private Long relationshipType;
}
最后是PartyAssetEntity.java
@Entity
@Table(name = "tb_party_asset")
public class PartyAsset extends BaseEntity<PartyAssetKey> {
private Long type;
// Getters and setters.
}
我用葡萄牙语写了一篇关于Spring Data JPA的帖子:http://wpattern.com/blog/post/2012/11/25/Introducao-ao-Spring-Data-JPA-(Contextualizacao)-Parte-01.aspx
氰
答案 1 :(得分:0)
@Techky你通过尝试复合键的所有选项做得很好,同时我也得到了完全相同的错误。
对于使用@EmbeddedId的情况,这是我的解决方案。这段代码我在一个类中编写,在Entity类中。
MyEntity.java
@Entity
@Table(name = "myTable")
public class MyEntity extends GenericPersistableEntity implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
MyEntityPrimaryKeys id;//Composite Primary key
//Composite fields can be declared here for getter and setters
@Column(name = "ROLLNO")
private Long RollNo;
//Composite fields can be declared here for getter and setters
@Column(name = "AGE")
private Long age;
@Column(name = "OtherFields"
private Long OtherFields;
//getter and setters comes here
}
@Embeddable
class MyEntityPrimaryKeys implements Serializable{
private static final long serialVersionUID = 1L;
@Column(name = "ROLLNO")
Long RollNo;
@Column(name = "AGE")
Long age;
@Override
public int hashCode() {
HashCodeBuilder hcb = new HashCodeBuilder();
hcb.append(RollNo);
hcb.append(age);
return hcb.toHashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof MyEntityPrimaryKeys)) {
return false;
}
MyEntityPrimaryKeys that = (MyEntityPrimaryKeys) obj;
EqualsBuilder eb = new EqualsBuilder();
eb.append(RollNo, that.RollNo);
eb.append(age, that.age);
eb.append(tonMonth, that.tonMonth);
eb.append(tonYear, that.tonYear);
return eb.isEquals();
}
}
希望这会有所帮助!!