0

我正在尝试使用 JPA2 映射以下数据库结构:

ASSET
ID: assetId
...

PARTY
ID: partyId
...

PARTYASSET
ID: partyId
ID: assetId
ID: relationshipType

PARTYASSET 的主键是 PARTY 和 ASSET 的外键和一个附加列的组合: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:

派对资产类

@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 的替代品

派对资产类

@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

派对资产类

@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:创建 com.ardan1.propertymanagement.test.config.TestApplicationContext 类中定义的名称为“entityManagerFactoryBean”的 bean 时出错:调用 init 方法失败;嵌套异常是 java.lang.NullPointerException 引起:java.util.Hashtable.put(Unknown Source) at java.util.Properties.setProperty(Unknown Source) at org.hibernate.cfg.annotations.SimpleValueBinder 的 java.lang.NullPointerException .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:

我有以下库(使用 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>
4

2 回答 2

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);
    }

}

资产实体.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

赛亚。

于 2013-04-01T11:54:57.050 回答
0

@Techky你通过尝试复合键的所有选项做得很好,巧合的是,我也得到了所有场景完全相同的错误。

对于使用@EmbeddedId 的情况,这是我的解决方案。我在一个类本身中编写了这段代码,在实体类中。

  • Class MyEntity - 这是我的表的实际实体类。“OtherFields”是那些不属于主键的字段。
  • Class MyEntityPrimaryKeys - 这是为我的复合键创建的类,它为我的“MyEntity”类创建主键。这里 ROLLNO 和 AGE 一起构成一个主键。

我的实体.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();
    }
}

希望这可以帮助!!

于 2018-04-24T11:27:13.110 回答