【发布时间】:2018-05-15 15:37:47
【问题描述】:
我需要对 OneToOne 和 ManyToOne 关系的几个 JoinColumns 设置唯一约束,但是即使我在 @JoinColumn 注释中正确设置了名称,Hibernate 似乎也找不到这些列。 这对我来说似乎很奇怪,因为同样的约束在 Liquibase 上运行良好。
这是我的实体类:
package entities;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import org.springframework.data.elasticsearch.annotations.Document;
import java.io.Serializable;
import java.util.Objects;
/**
* A MyAnswer.
*/
@Entity
@Table(name = "my_answer",
uniqueConstraints = @UniqueConstraint(columnNames = {"question_id, questionnaire_id", "user_id"})
)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Document(indexName = "myanswer")
public class MyAnswer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@Column(name = "mycheck")
private String mycheck;
@OneToOne
@JoinColumn
private Answer answer;
@OneToOne
@JoinColumn(name = "question_id")
private Question question;
@OneToOne
@JoinColumn(name = "questionnaire_id")
private Questionnaire questionnaire;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getMycheck() {
return mycheck;
}
public MyAnswer mycheck(String mycheck) {
this.mycheck = mycheck;
return this;
}
public void setMycheck(String mycheck) {
this.mycheck = mycheck;
}
public Answer getAnswer() {
return answer;
}
public MyAnswer answer(Answer answer) {
this.answer = answer;
return this;
}
public void setAnswer(Answer answer) {
this.answer = answer;
}
public Question getQuestion() {
return question;
}
public MyAnswer question(Question question) {
this.question = question;
return this;
}
public void setQuestion(Question question) {
this.question = question;
}
public Questionnaire getQuestionnaire() {
return questionnaire;
}
public MyAnswer questionnaire(Questionnaire questionnaire) {
this.questionnaire = questionnaire;
return this;
}
public void setQuestionnaire(Questionnaire questionnaire) {
this.questionnaire = questionnaire;
}
public User getUser() {
return user;
}
public MyAnswer user(User user) {
this.user = user;
return this;
}
public void setUser(User user) {
this.user = user;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MyAnswer myAnswer = (MyAnswer) o;
if (myAnswer.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), myAnswer.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public String toString() {
return "MyAnswer{" +
"id=" + getId() +
", mycheck='" + getMycheck() + "'" +
"}";
}
}
抛出的异常日志下方:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to create unique key constraint (question_id, questionnaire_id, user_id) on table my_answer: database column 'question_id, questionnaire_id' not found. Make sure that you use the correct column name which depends on the naming strategy in use (it may not be the same as the property name in the entity, especially for relational types)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1080)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at project.App.main(App.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.hibernate.AnnotationException: Unable to create unique key constraint (question_id, questionnaire_id, user_id) on table my_answer: database column 'question_id, questionnaire_id' not found. Make sure that you use the correct column name which depends on the naming strategy in use (it may not be the same as the property name in the entity, especially for relational types)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.buildUniqueKeyFromColumnNames(InFlightMetadataCollectorImpl.java:2074)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.buildUniqueKeyFromColumnNames(InFlightMetadataCollectorImpl.java:1935)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processUniqueConstraintHolders(InFlightMetadataCollectorImpl.java:1923)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1595)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:858)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:885)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:382)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
... 19 common frames omitted
2018-05-15 17:25:20.943 WARN 16173 --- [neut-Executor-1] com.zaxxer.hikari.pool.ProxyConnection : HikariPool-1 - Connection org.postgresql.jdbc.PgConnection@669c1cb9 marked as broken because of SQLSTATE(08003), ErrorCode(0)
【问题讨论】:
-
快速提问:如果删除唯一约束声明,应用程序启动正常吗?
-
是的,它开始就好了
-
您是如何创建表格的?您是否使用 JPA 设置从您配置的注释创建表?
-
尝试添加命名策略。 org.hibernate.cfg.ImprovedNamingStrategy
-
表是Liquibase在启动时创建的,列名正确。让我们尝试使用建议的命名策略
标签: java hibernate jpa unique-constraint