#java #hibernate
#java #переход в спящий режим
Вопрос:
Хотя я провел небольшое исследование по этому вопросу и обнаружил множество угроз, открытых в Интернете, я не смог решить свою проблему. Я прилагаю свой код:
Triple.java первичный ключ создается 3 URI из трех разных концепций, но это один и тот же столбец (это проблема?)
@Entity
@IdClass(ConceptPk.class)
@Table(name = "triple")
public class TripleDBModel {
protected List<Annotation> annotations;
public String conceptUriSubject;
public String conceptUriObject;
public String conceptUriPredicate;
public String id;
@ManyToMany(
cascade={CascadeType.ALL},
fetch=FetchType.LAZY
)
@JoinTable(name = "triple_has_annotation",
joinColumns=@JoinColumn(name="annotation_id"),
inverseJoinColumns={@JoinColumn(name="uri_concept_subject", referencedColumnName="triple_id"), @JoinColumn(name="uri_concept_object", referencedColumnName="triple_id"), @JoinColumn(name="uri_concept_predicate", referencedColumnName="triple_id")
})//EDIT
public List<Annotation> getAnnotations() {
return annotations;
}
public void setAnnotations(List<Annotation> annotations) {
this.annotations = annotations;
}
@Id
@Column(name = "uri_concept_subject", length = 100)
public String getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(String conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
@Id
@Column(name = "uri_concept_object", length = 100)
public String getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(String conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
@Id
@Column(name = "uri_concept_predicate", length = 100)
public String getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(String conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
@Id
@Column(name = "triple_id", unique = true, nullable = false)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
ConceptPk.java
@Embeddable
public class ConceptPk implements java.io.Serializable {
private static final long serialVersionUID = 1L;
public String conceptUriSubject;
public String conceptUriObject;
public String conceptUriPredicate;
@Id
@Column(name = "uri", length = 100, unique = true, nullable = false)
public String getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(String conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
@Id
@Column(name = "uri", length = 100, unique = true, nullable = false)
public String getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(String conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
@Id
@Column(name = "uri", length = 100, unique = true, nullable = false)
public String getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(String conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
Annotation.java
@Entity
@Table(name = "annotations")
public class Annotation {
private Integer id;
private List<TripleDBModel> triples;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "annotation_id", unique = true, nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToMany(
cascade={CascadeType.ALL},
mappedBy = "annotations", //EDIT
fetch=FetchType.LAZY
)
public List<TripleDBModel> getTriples() {
return triples;
}
public void setTriples(List<TripleDBModel> triples) {
this.triples = triples;
}
Но я получаю эту ошибку:
Caused by: org.hibernate.AnnotationException: A Foreign key refering TripleDBModel from Annotation has the wrong number of column. should be 3
Что я делаю не так?? Заранее спасибо
Комментарии:
1. Почему вы присвоили имени столбца для всех 3 столбцов id в ConceptPK значение «uri»? Они должны быть разными, иначе они указывали бы на один и тот же столбец.
2. Поскольку первичный ключ представляет собой комбинацию 3 понятий, то 3 из них должны указывать на uri, идентификатор понятия
3. Вам все равно придется ссылаться на 3 разных столбца в наборе данных. Вы не можете заставить несколько наборов данных определять внешний ключ для 4-го. Внешний ключ определен в
Tripple
таблице, и я сомневаюсь, что в нем есть столбецuri
, не так ли?4. Я отредактировал свой вопрос, поле
annotation_id
находится не в Triple, а в Annotation. Первичный ключ Triple состоит из 3 annotation_id, состоящих из 3 разных аннотаций.annotation_id
это имя поля в базе данныхid
. Это правильно?5. Я добавил
triple_id
в качестве идентификатора Triple, что вы имели в виду??
Ответ №1:
Окончательное решение таково:
ConceptPk.java
@Embeddable
public class ConceptPk implements java.io.Serializable {
private static final long serialVersionUID = 1L;
public Concept conceptUriSubject;
public Concept conceptUriObject;
public Concept conceptUriPredicate;
@Id
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="uri_concept_subject")
public Concept getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(Concept conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
@Id
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="uri_concept_object")
public Concept getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(Concept conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
@Id
@ManyToOne(cascade=CascadeType.MERGE)
@JoinColumn(name="uri_concept_predicate")
public Concept getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(Concept conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
Triple.java
@Entity
@IdClass(ConceptPk.class)
@Table(name = "triple")
public class TripleDBModel {
protected List<Annotation> annotations;
public Concept conceptUriSubject;
public Concept conceptUriObject;
public Concept conceptUriPredicate;
@ManyToMany(
cascade={CascadeType.ALL },
fetch=FetchType.LAZY
)
@JoinTable(name = "triple_has_annotation",
joinColumns={@JoinColumn(name="uri_concept_subject"), @JoinColumn(name="uri_concept_object"), @JoinColumn(name="uri_concept_predicate") },
inverseJoinColumns=@JoinColumn(name="annotation_id") )
public List<Annotation> getAnnotations() {
return annotations;
}
public void setAnnotations(List<Annotation> annotations) {
this.annotations = annotations;
}
@Id
@Column(name = "uri_concept_subject", length = 100)
public Concept getConceptUriSubject() {
return conceptUriSubject;
}
public void setConceptUriSubject(Concept conceptUriSubject) {
this.conceptUriSubject = conceptUriSubject;
}
@Id
@Column(name = "uri_concept_object", length = 100)
public Concept getConceptUriObject() {
return conceptUriObject;
}
public void setConceptUriObject(Concept conceptUriObject) {
this.conceptUriObject = conceptUriObject;
}
@Id
@Column(name = "uri_concept_predicate", length = 100)
public Concept getConceptUriPredicate() {
return conceptUriPredicate;
}
public void setConceptUriPredicate(Concept conceptUriPredicate) {
this.conceptUriPredicate = conceptUriPredicate;
}
}
Ответ №2:
Я не уверен, что это является причиной получаемого вами сообщения об ошибке, но в вашем сопоставлении есть несколько ошибок:
- У каждого из
@JoinColumn
в вашемinverseJoinColumns
атрибуте должен быть указан свойreferencedColumnName
атрибут. - Значения атрибутов joinColumns и inverseJoinColumns должны быть переключены. joinColumns используется для ссылки на исходный объект. inverseJoinColumns используется для ссылки на целевой объект.
mappedBy
Атрибут должен бытьannotations
, а неannotation
- (несвязанный, но, вероятно, неверный) :
cascade=CascadeType.ALL
вероятно, это не то, что вы хотите для многие-ко-многим. Вы не хотите удалять все аннотации тройки при удалении этой тройки, поскольку на эти аннотации ссылаются другие тройки.
Комментарии:
1. Спасибо за ответ, но я все еще получаю ту же ошибку. Ссылочное имяcolumnname такое же для trhee, будет ли это проблемой?? В любом случае, я проверю CascadeType, спасибо
2. Имя ссылочного столбца должно быть именем столбца в тройной таблице, а не случайным именем (т. Е. Оно используется, чтобы сообщить Hibernate, что столбец uri_concept_subject таблицы triple_has_annotation ссылается на столбец uri_concept_subject тройной таблицы. И я думаю, что нашел проблему: значения атрибутов joinColumns и inverseJoinColumns должны быть переключены.
3. Ссылочный столбец — это имя столбца в таблице аннотаций, то есть
annotation_id
, потому что я хочу выполнить соединение между Triple и Annotation.uri_concept_subject
это имя в базе данных поляconceptUriSubject
на Triple.java Это правильно?? Спасибо
Ответ №3:
@ManyToMany(
cascade={CascadeType.ALL},
mappedBy = "annotation",
fetch=FetchType.LAZY
)
public List<TripleDBModel> getTriples() {
return triples;
}
mappedBy
Должно быть «аннотацииs«.
Редактировать: Взгляните на этот wikibook, особенно на нижний раздел. Это довольно хорошая ссылка для сопоставлений ассоциаций и т.д.