2016-12-26 61 views
0

我们有2个实体帐户和转让关系一对多。现在我尝试保存传输到我的数据库,所以我创建一个视图与必要的字段,并通过iban_sender有连接器。Spring Boot - OneToMany并保存实体

我会尽量简化我的问题,让阅读更加舒适。

Account.java

@Entity 
@Table(name = "bank_account") 
public class Account { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", nullable = false, updatable = false) 
    private int id; 
    @Column(name = "iban", nullable = false, unique = true) 
    private String iban; 
    @Column(name = "balance", nullable = false, unique = true) 
    private float balance; 
    @Column(name = "date_created", nullable = false, unique = true) 
    @Temporal(TemporalType.DATE) 
    private Date dateCreated; 
    @ManyToOne 
    @JoinColumn(name = "user_id") 
    private User user; 

    @OneToMany(mappedBy = "account",cascade = CascadeType.ALL,fetch = FetchType.EAGER) 
    private Set<Transfer> transfers; 

    public Account(){} 

    public Account(String iban, float balance, Date dateCreated,User user) { 
     this.iban = iban; 
     this.balance = balance; 
     this.dateCreated = dateCreated; 
     this.user = user; 
    } 

} 

Transfer.java

@Entity 
@Table(name = "account_transfer") 
public class Transfer { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", nullable = false, updatable = false) 
    private int id; 
    @Column(name = "iban_receiver", nullable = false, unique = true) 
    private String ibanReceiver; 
    @Column(name = "title", nullable = false, unique = true) 
    private String title; 
    @Column(name = "receiver", nullable = false, unique = true) 
    private String receiver; 
    @Column(name = "amount", nullable = false, unique = true) 
    private float amount; 
    @Column(name = "date_created", nullable = false, unique = true) 
    @Temporal(TemporalType.DATE) 
    private Date dateCreated; 

    @ManyToOne 
    @JoinColumn(name = "iban_sender") 
    private Account account; 


    public Transfer(){} 

    public Transfer(String ibanReceiver, String title, String receiver, float amount, Date dateCreated, Account account) { 
     this.ibanReceiver = ibanReceiver; 
     this.title = title; 
     this.receiver = receiver; 
     this.amount = amount; 
     this.dateCreated = dateCreated; 
     this.account = account; 
    } 
} 

AccountController.java

@Controller 
public class AccountController { 

    private final TransferService transferService; 

    @Autowired 
    public AccountController(TransferService transferService) { 
     this.transferService = transferService; 
    } 

    @RequestMapping(value = "/account/transfer", method = RequestMethod.GET) 
    public String transferForm(HttpServletRequest request,Authentication authentication){ 
     CurrentUser currentUser = (CurrentUser) authentication.getPrincipal(); 
     Set<Account> accounts = currentUser.getAccounts(); 
     String FirstIban = accounts.iterator().next().getIban(); // TODO: Make a list of accounts 

     request.setAttribute("iban_sender",FirstIban); 
     return "account_transfer"; 
    } 
    //TODO: create view of all accounts 

    @RequestMapping(value = "/account/transfer", method = RequestMethod.POST) 
    public String registerTrasnform(@Valid Transfer transfer, BindingResult bindingResult){ 
     if (bindingResult.hasErrors()) { 
      return "account_transfer"; 
     } 
     System.out.println("LOGI -- transfer" + transfer.toString()); 
     transferService.save(transfer); 
     return "redirect:/"; 
    } 
} 

最后我的看法:

<#-- @ftlvariable name="_csrf" type="org.springframework.security.web.csrf.CsrfToken" --> 
<#-- @ftlvariable name="error" type="java.util.Optional<String>" --> 
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <title>Log in</title> 
</head> 
<body> 
<nav role="navigation"> 
    <ul> 
     <li><a href="/">Home</a></li> 
    </ul> 
</nav> 

<h1>Make transfer</h1> 

<form role="form" action="/account/transfer" method="post"> 
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 

    <div> 
     <label for="iban_sender">Account number</label> 
     <input type="text" name="iban_sender" id="iban_sender" value="${iban_sender}" disabled="disabled" /> 
    </div> 
    <div> 
     <label for="iban_receiver">Account number</label> 
     <input type="text" name="ibanReceiver" id="iban_receiver" required autofocus/> 
    </div> 
    <div> 
     <label for="title">Title</label> 
     <input type="text" name="title" id="title" required/> 
    </div> 
    <div> 
     <label for="receiver">Receiver</label> 
     <input type="text" name="receiver" id="receiver" required/> 
    </div> 
    <div> 
     <label for="amount">Amount</label> 
     <input type="number" name="amount" id="amount" required/> 
    </div> 
    <button type="submit">Send</button> 
</form> 


</body> 
</html> 

我的错误:

ERROR 1456 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'iban_sender' cannot be null ERROR 1456 --- [nio-8080-exec-9] 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

错误跟踪:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'iban_sender' cannot be null 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) 
at com.mysql.jdbc.Util.getInstance(Util.java:387) 
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:934) 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3966) 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3902) 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2526) 
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2673) 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549) 
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861) 
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073) 
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009) 
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098) 
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994) 
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) 
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96) 
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58) 
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032) 
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3558) 
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:98) 
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:490) 
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:195) 
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:179) 
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:214) 
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324) 
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288) 
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194) 
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125) 
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84) 
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206) 
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149) 
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75) 
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811) 
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784) 
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789) 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181) 
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.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344) 
at com.sun.proxy.$Proxy71.persist(Unknown Source) 
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.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291) 
at com.sun.proxy.$Proxy71.persist(Unknown Source) 
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:394) 
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.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:442) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:427) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:381) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:512) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:267) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) 
at com.sun.proxy.$Proxy81.save(Unknown Source) 
at com.ematkuz.ebank.service.transfer.TransferServiceImpl.save(TransferServiceImpl.java:25) 
at com.ematkuz.ebank.controller.AccountController.registerTrasnform(AccountController.java:46) 
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.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:644) 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:105) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658) 
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:745) 

似乎春天不承认接头列iban_sender。我的问题是: 1.我做错了什么? 2.我可以从我的看法iban_sender吗?这将解决问题,因为我可以创建Transform对象。

+0

这看起来像你想它分配Account'的'实例之前保存Transfer'的'一个实例。你能提供完整的堆栈跟踪吗? – oschlueter

+0

这正是发生了什么,但我不知道如何以简单的方式解决这个问题。添加错误跟踪。 – matkuz

+0

您的'Transfer'实例是否没有对'Account'实例的引用,或者该引用尚未保存到数据库? – oschlueter

回答

0

您在保存帐户转账时未设置帐户对象。

解决的办法之一可能是:

//Will not persist in database 
@Transient 
private int ibanSenderId; 

Account account = //fetch using tranfer.getIbanSenderId() from database 

transfer.setAccount(account); 

transferService.save(transfer);