Mes*_*yah 4 java spring hibernate jpa
我正在使用 Hibernate 制作 Spring 应用程序,我只是想让我的实体之间的关系正常工作。我为所有外键设置了注释,现在出现“实体映射中的重复列”错误。我试图在 SO 上找到解决方案,但我并没有真正理解一些答案,而且我认为它们不适用于我的代码。我之前在另一个项目中遇到过这个问题,其中所有 ID 字段都被命名id
,当我明确定义列名@Column(name = "")
并在@JoinColumn
参数中键入该名称时,它起作用了。现在我遇到了同样的错误,但是为 ID 字段定义显式名称并没有帮助。
这是我的实体类:
@Entity
public class Task implements Serializable, Discussable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "task_id")
private long id;
private String name;
@ManyToMany
@JoinTable(
name = "user_task",
joinColumns = @JoinColumn(name = "task_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private Set<User> assigneeUsers;
@Enumerated(EnumType.ORDINAL)
private Status status; //alt + enter
private Priority priority;
private Date deadline;
private String description;
@ManyToOne
@JoinColumn(name = "task_id")
private Task parentTask;
@OneToMany(mappedBy = "parentTask")
private Set<Task> subtasks;
@Enumerated(EnumType.ORDINAL)
private Type type;
@OneToOne(cascade = CascadeType.REMOVE)
@JoinColumn(name = "channel_id")
private Channel channel;
@ManyToOne
@JoinColumn(name = "project_id")
private Project project;
// getters, setters and default constructor
Run Code Online (Sandbox Code Playgroud)
我在尝试编译时得到的结果是:
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 javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1078) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at com.github.mesayah.assistance.AssistanceApplication.main(AssistanceApplication.java:20) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:370) ~[spring-orm-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:359) ~[spring-orm-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
... 16 common frames omitted
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.github.mesayah.assistance.model.Task column: task_id (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:830) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:848) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:870) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:605) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.mapping.RootClass.validate(RootClass.java:265) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:443) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
... 22 common frames omitted
Run Code Online (Sandbox Code Playgroud)
所以我认为问题在于private Task parentTask;
或者private Set<User> asigneeUsers;
因为只有这些成员使用“task_id”的映射。但我无法弄清楚这段代码有什么特别的问题。
您看到的错误:
实体映射中的重复列: com.github.mesayah.assistance.model.Task 列:task_id (应该用 insert="false" update="false" 映射)
这告诉您task_id
实体内的列Task
已与多个属性相关联。
您可以将同一列关联到映射中的多个属性;但是,只有一个映射可以控制持久性行为,而其他映射是只读的。
作为一个简单的例子:
public class MyEntity {
@Column(name = "NAME")
private String name;
@Column(name = "NAME", insertable = false, updatable = false)
private String name2;
}
Run Code Online (Sandbox Code Playgroud)
name
此示例中的属性将始终被插入和更新。此属性控制列的持久性NAME
。该属性name2
永远不会被插入或更新,只是作为column的只读字段NAME
。
如果我没有包含insertable = false, updatable = false
在列映射中,那么 Hibernate 会给出与您看到的相同的错误消息。
既然您了解了错误消息的技术原因,您的问题就是 Maciej Kowalski 提到的。您可能应该以不同的方式映射您的父引用:
@ManyToOne
@Column(name = "parent_task_id")
private Task parentTask;
Run Code Online (Sandbox Code Playgroud)
从概念上讲,您正在寻找的是您的孩子Task
,其中有一列task_id
还有第二列将外键引用到 parent Task
。这个外键必须存储在一个新的列中,恰当地命名为parent_task_id
。