【问题标题】:many to one relationship between composite keys组合键之间的多对一关系
【发布时间】:2014-06-19 14:03:00
【问题描述】:

我正在使用 hibernate 和 JPA 构建一个 spring mvc 应用程序,它需要对一些底层 MYSQL 数据表进行建模,每个表都有具有相同两种数据类型的复合键,因此每个表都有自己的复合键类,即使所有复合键基于具有完全相同属性名称的相同两种数据类型。当我尝试编译应用程序时遇到休眠映射错误,我想知道这是否可能是因为休眠可能无法等同于不同的主键类。 谁能告诉我如何解决这个问题,以便我的应用能够编译?

这是我的Description 类的一部分,它根据它们对应的复合主键类在DescriptionConcept 类之间建立ManyToOne 关系:

@ManyToOne
@JoinColumn(name="descriptionPK", referencedColumnName = "conceptPK")
private Concept concept;

这是我得到的错误:

Caused by: org.hibernate.MappingException:  
Unable to find column with logical name:  
conceptPK in org.hibernate.mapping.Table(sct2_concept) and its related supertables and secondary tables

ConceptPK的代码是:

@Embeddable
class ConceptPK implements Serializable {

@Column(name="id", nullable=false)
protected BigInteger id;

@Column(name="effectiveTime", nullable=false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime effectiveTime;

public ConceptPK() {}
public ConceptPK(BigInteger bint, DateTime dt) {
    this.id = bint;
    this.effectiveTime = dt;
}

/** getters and setters **/
public DateTime getEffectiveTime(){return effectiveTime;}
public void setEffectiveTime(DateTime ad){effectiveTime=ad;}

public void setId(BigInteger id) {this.id = id;}
public BigInteger getId() {return id;}

@Override
public boolean equals(Object obj) { 
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    final ConceptPK other = (ConceptPK) obj;
    if (effectiveTime == null) {
        if (other.effectiveTime != null) return false;
    } else if (!effectiveTime.equals(other.effectiveTime)) return false;
    if (id == null) {
        if (other.id != null) return false;
    } else if (!id.equals(other.id)) return false;
    return true;
}

@Override
public int hashCode() { 
    int hash = 3;
    hash = 53 * hash + ((effectiveTime == null) ? 0 : effectiveTime.hashCode());
    hash = 53 * hash + ((id == null) ? 0 : id.hashCode());
    return hash;
}
}

DescriptionPK的代码是:

@Embeddable
class DescriptionPK implements Serializable {
@Column(name="id", nullable=false)
protected BigInteger id;

@Column(name="effectiveTime", nullable=false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime effectiveTime;

public DescriptionPK() {}
public DescriptionPK(BigInteger bint, DateTime dt) {
    this.id = bint;
    this.effectiveTime = dt;
}

/** getters and setters **/
public DateTime getEffectiveTime(){return effectiveTime;}
public void setEffectiveTime(DateTime ad){effectiveTime=ad;}

public void setId(BigInteger id) {this.id = id;}
public BigInteger getId() {return id;}

@Override
public boolean equals(Object obj) { 
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    final DescriptionPK other = (DescriptionPK) obj;
    if (effectiveTime == null) {
        if (other.effectiveTime != null) return false;
    } else if (!effectiveTime.equals(other.effectiveTime)) return false;
    if (id == null) {
        if (other.id != null) return false;
    } else if (!id.equals(other.id)) return false;
    return true;
}

@Override
public int hashCode() { 
    int hash = 3;
    hash = 53 * hash + ((effectiveTime == null) ? 0 : effectiveTime.hashCode());
    hash = 53 * hash + ((id == null) ? 0 : id.hashCode());
    return hash;
}
}

【问题讨论】:

    标签: java spring hibernate spring-mvc jpa


    【解决方案1】:

    您需要更改@ManyToOne 注释以使用多个列,如下所示,并且如果所有属性都相同,则无需创建重复的两个可嵌入类ConceptPK 和DescriptionPK,只需创建一个EmbeddablePK 并在两个实体中使用即可。

    @OneToMany(mappedBy = "concept", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
        public List<Description> descriptions = new LinkedList<Description>();
    

    和描述类:

    @ManyToOne
    @JoinColumns({ @JoinColumn(name = "A_COLUMN", referencedColumnName = "A_COLUMN", insertable = false, updatable = false),
            @JoinColumn(name = "B_COLUMN", referencedColumnName = "B_COLUMN", insertable = false, updatable = false),
    })
    public Concept concept;
    

    【讨论】:

    • 基础数据表可以不同,只要两个表中的列名相同,如下所示,您可以有一个可嵌入的MyPrimaryKey 并在两个实体中使用相同的。 @Embeddable public class MyPrimaryKey 实现 Serializable { ... @EmbeddedId private MyPrimaryKey myPrimaryKey; @EmbeddedId private MyPrimaryKey myPrimaryKey;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 2012-10-18
    • 1970-01-01
    相关资源
    最近更新 更多