2016-11-23 126 views
1

我得到关于休眠键和外键约束的问题。春休眠Forgein键约束

我有以下情形(伪java代码)。我有一个父类(部)

@Entity 
public class Department { 

    @Id 
    private Long id; 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "department", cascade = CascadeType.ALL) 
    List<Person> persons; 

    public void addToPersons(Person p) { 
    if (this.persons == null) { 
     this.persons = new ArrayList<>(); 
    } 
    this.persons.add(p); 
    p.setDepartment(this); 
    } 

    public void setId(Long id) { 
    this.id = id; 
    } 

} 

和子类(人)

@Entity 
public class Person { 

    @Id 
    private String name; 

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    private List<Person> followers; 

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "followers") 
    private List<Person> following; 

    @ManyToOne(fetch = FetchType.LAZY) 
    private Department department; 

    public void addToFollowers(Person p) { 
    if (this.followers == null) { 
     this.followers = new ArrayList<>(); 
    } 
    if (!this.followers.contains(p)) { 
     this.followers.add(p); 
    } 
    } 

    public void addToFollowing(Person p) { 
    if (this.following == null) { 
     this.following = new ArrayList<>(); 
    } 
    if (!this.following.contains(p)) { 
     this.following.add(p); 
    } 
    } 

    public void setDepartment(Department department) { 
    this.department = department; 
    } 

    public void setName(String name) { 
    this.name = name; 
    } 

    @Override 
    public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 
    Person that = (Person) o; 
    return name != null ? name.equals(that.name) : that.name == null; 
    } 

} 

完成,仓库类

public interface DepartmentRepository extends CrudRepository<Department, Long> {} 

从而导致该异常控制器

@RestController 
public class MainController { 

    @Autowired 
    private DepartmentRepository departmentRepository; 

    @RequestMapping("/") 
    @ResponseBody 
    public String index() { 
    Department d1 = new Department(); 
    d1.setId(1L); 

    Department d2 = new Department(); 
    d2.setId(2L); 

    Person john = new Person(); 
    john.setName("John"); 

    Person alice = new Person(); 
    alice.setName("Alice"); 

    john.addToFollowers(alice); 
    alice.addToFollowing(john); 

    d1.addToPersons(john); 
    d2.addToPersons(alice); 

    departmentRepository.save(d1); // <-- throws violation exception 

    return "foo"; 
    } 

} 

我猜它引发的冲突异常,因为该部门D2尚未保存,但有可能做到这一点不明确保存的所有实体的entites之前?

谢谢!

UPDATE

完成了代码。异常原因:

2016-11-24 11:45:40.513 ERROR 19927 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : INSERT on table 'PERSON' caused a violation of foreign key constraint 'FK_R2AEQQXC7UWBN48SHRHMAI8CX' for key (2). The statement has been rolled back. 
2016-11-24 11:45:40.514 INFO 19927 --- [nio-8080-exec-1] o.h.e.j.b.internal.AbstractBatchImpl  : HHH000010: On release of batch it still contained JDBC statements 
2016-11-24 11:45:40.526 ERROR 19927 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause 

org.apache.derby.iapi.error.StandardException: INSERT on table 'PERSON' caused a violation of foreign key constraint 'FK_R2AEQQXC7UWBN48SHRHMAI8CX' for key (2). The statement has been rolled back. 
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.sql.execute.ForeignKeyRIChecker.doCheck(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.sql.execute.RISetChecker.doFKCheck(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.sql.execute.InsertResultSet.open(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeLargeUpdate(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(Unknown Source) ~[derby-10.12.1.1.jar:na] 
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3124) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3581) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:104) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] 
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) ~[spring-orm-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) ~[spring-tx-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) ~[spring-tx-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485) ~[spring-tx-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291) ~[spring-tx-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131) ~[spring-data-jpa-1.9.1.RELEASE.jar:na] 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at com.sun.proxy.$Proxy69.save(Unknown Source) ~[na:na] 
at com.ottogroup.test.MainController.index(MainController.java:40) ~[classes/:na] 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_80] 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_80] 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_80] 
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_80] 
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) ~[tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_80] 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_80] 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.28.jar:8.0.28] 
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_80] 
+0

您没有任何'部门'在这里。你可以添加方法和完整的堆栈跟踪。 –

回答

0
@Entity(name = "department")  
class Department { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int idx 

    @OneToMany(mappedBy = "department", cascade = { CascadeType.ALL }) 
    List<Person> person; 

    // getter, setter... 
} 

@Entity(name = "Person") 
class Person { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int idx; 

    @ManyToOne 
    @JoinColumn(name = "department_id") 
    private Department department; 

    // getter, setter... 
} 


Department department = new Department(); 
Person p1 = new Person(); 
Person p2 = new Person(); 

p1.setDepartment(department); 
p2.setDepartment(department); 

personRepository.save(p1); 
personRepository.save(p2); 
0

在你d.addToPersons(p1);实现确保你的部门设置到人,以及,

public void addToPersons(Person person){ 
person.setDepartment(this); 
this.persons.add(person); 
} 

同样适用于其他关系