отношения один к одному между составными ключами

1

Я создаю приложение mvc Spring с hibernate и JPA, которому необходимо смоделировать несколько базовых таблиц данных MYSQL, каждая из которых имеет составные ключи с одинаковыми двумя типами данных, поэтому каждая таблица имеет свой собственный составной класс ключей, хотя все составные ключи основаны на тех же двух типах данных с одинаковыми именами свойств. Я получаю ошибку сопоставления hibernate, когда пытаюсь скомпилировать приложение, и мне интересно, может ли это быть из-за того, что спящий режим не может сравнивать различные классы первичных ключей. Может ли кто-нибудь показать мне, как исправить это, чтобы мое приложение скомпилировалось?

Вот часть моего класса Description которая устанавливает отношения ManyToOne между классами Description и Concept на основе их соответствующих составных классов первичного ключа:

@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;
}
}
Теги:
spring
spring-mvc
hibernate
jpa

1 ответ

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;
  • 0
    Базовая таблица данных может отличаться, если имена столбцов в двух таблицах одинаковы, как MyPrimaryKey ниже, вы можете иметь один встраиваемый MyPrimaryKey и использовать его в обеих сущностях. @Embeddable открытый класс MyPrimaryKey реализует Serializable {... @EmbeddedId private MyPrimaryKey myPrimaryKey; @EmbeddedId private MyPrimaryKey myPrimaryKey;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню