2

I have two JPA entities User and Authority, User the parent and Authority is the child. There is one to many relationship between User and Authority.

User -

@Data
@Entity
@Table(name = "users", uniqueConstraints={ @UniqueConstraint(columnNames={"username"})})
public class User {

    @Id
    @CustomEmailValidator
    @Size.List ({
            @Size(min=5, message="The field must be at least {min} characters"),
            @Size(max=100, message="The field must be less than {max} characters")
    })
    private String username;

    @Basic
    @Column(name = "enabled", columnDefinition = "BIT", length = 1)
    private boolean enabled;

    @OneToMany(cascade = {CascadeType.ALL,CascadeType.PERSIST,CascadeType.MERGE}, mappedBy = "user")
    @Column(nullable = false)
    private List<Authority> authorities = new ArrayList<>();
}

Authority -

@Data
@Entity
@Table(name ="authorities")
public class Authority {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Version
    private Integer version;

    @NotNull
    @Size.List ({
            @Size(min=5, message="The field must be at least {min} characters"),
            @Size(max=100, message="The field must be less than {max} characters")
    })
    private String authority;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "username", nullable=false)
    private User user;
}

I have exposed User as a Spring Data Rest repository. When I do http://localhost/api/users I am able to see uses to list along with Authorities. However when I try to create a user along with authorities using the following json -

{
   "username": "cmsdeveloper222@amnesty.org.in",
   "enabled": true,
   "authorities": [
    {

       "authority": "ROLE_ADMIN"
    }
    ]

}

I get the following error -

{
    "cause": {
        "cause": {
            "cause": null,
            "message": "Column 'username' cannot be null"
        },
        "message": "could not execute statement"
    },
    "message": "could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
}

The underlying exception is -

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'username' cannot be null
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_40]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_40]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_40]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_40]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.Util.getInstance(Util.java:360) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:971) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3887) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3823) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2530) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1907) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2141) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2077) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2062) ~[mysql-connector-java-5.1.34.jar:5.1.34]
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    ... 151 common frames omitted
Hibernate: select count(campaign0_.id) as col_0_0_ from Campaign campaign0_
Hibernate: select campaign0_.id as id1_0_, campaign0_.campaignId as campaign2_0_, campaign0_.emailOfTheCreator as emailOfT3_0_, campaign0_.endDate as endDate4_0_, campaign0_.name as name5_0_, campaign0_.startDate as startDat6_0_, campaign0_.status as status7_0_, campaign0_.summary as summary8_0_, campaign0_.version as version9_0_ from Campaign campaign0_ limit ?
Hibernate: select user0_.username as username1_3_1_, user0_.enabled as enabled2_3_1_, authoritie1_.username as username4_3_3_, authoritie1_.id as id1_2_3_, authoritie1_.id as id1_2_0_, authoritie1_.authority as authorit2_2_0_, authoritie1_.username as username4_2_0_, authoritie1_.version as version3_2_0_ from users user0_ left outer join authorities authoritie1_ on user0_.username=authoritie1_.username where user0_.username=?
Hibernate: insert into users (enabled, username) values (?, ?)
Hibernate: insert into authorities (authority, username, version) values (?, ?, ?)
16:48:14.260 [http-nio-8080-exec-1] WARN  o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 1048, SQLState: 23000
16:48:14.267 [http-nio-8080-exec-1] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Column 'username' cannot be null
16:48:14.271 [http-nio-8080-exec-1] WARN  o.h.e.jdbc.spi.SqlExceptionHelper - SQL Warning Code: 1048, SQLState: 23000
16:48:14.271 [http-nio-8080-exec-1] WARN  o.h.e.jdbc.spi.SqlExceptionHelper - Column 'username' cannot be null
16:48:14.308 [http-nio-8080-exec-1] ERROR o.s.d.r.w.AbstractRepositoryRestController - could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:248) ~[spring-orm-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:214) ~[spring-orm-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417) ~[spring-orm-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) ~[spring-tx-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[spring-tx-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) ~[spring-tx-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122) ~[spring-data-jpa-1.7.2.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at com.sun.proxy.$Proxy98.save(Unknown Source) ~[na:na]
    at org.springframework.data.rest.core.invoke.CrudRepositoryInvoker.invokeSave(CrudRepositoryInvoker.java:106) ~[spring-data-rest-core-2.2.2.RELEASE.jar:na]
    at org.springframework.data.rest.webmvc.RepositoryEntityController.createAndReturn(RepositoryEntityController.java:414) ~[spring-data-rest-webmvc-2.2.2.RELEASE.jar:na]
    at org.springframework.data.rest.webmvc.RepositoryEntityController.postCollectionResource(RepositoryEntityController.java:232) ~[spring-data-rest-webmvc-2.2.2.RELEASE.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) ~[spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868) [spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:644) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:140) [spring-security-oauth2-2.0.2.RELEASE.jar:na]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [spring-web-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_40]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_40]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.20.jar:8.0.20]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_40]
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:211) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3558) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:98) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:492) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:197) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:181) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:216) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.jpa.event.internal.core.JpaMergeEventListener.saveWithGeneratedId(JpaMergeEventListener.java:73) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:271) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:251) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:189) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:886) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:868) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:277) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:460) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:255) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:317) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:186) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344) ~[spring-orm-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at com.sun.proxy.$Proxy93.merge(Unknown Source) ~[na:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291) ~[spring-orm-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at com.sun.proxy.$Proxy93.merge(Unknown Source) ~[na:na]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:410) ~[spring-data-jpa-1.7.2.RELEASE.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:416) ~[spring-data-commons-1.9.2.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:401) ~[spring-data-commons-1.9.2.RELEASE.jar:na]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:373) ~[spring-data-commons-1.9.2.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:486) ~[spring-data-commons-1.9.2.RELEASE.jar:na]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.5.RELEASE.jar:4.1.5.RELEASE]

Please help. What I am doing wrong? Why hibernate complains the username is null when I have mapping? Is it possible that my json is not converted properly?

Thanks, Vijay

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
Vijay Muvva
  • 1,063
  • 1
  • 17
  • 31

2 Answers2

6

Finally I found the solution. It is an issue with Jackson json unmarshalling. What is missing is a way to tell the object mapper about the one to many relationship, only then it will create parent and child objects properly upon which hibernate handles the rest of the stuff. Luckily Jackson has two annotations @JsonManagedReference, @JsonBackReference to tell the object mapper about the relationship. Updated code -

User.java

@Data
@Entity
@Table(name = "users", uniqueConstraints={ @UniqueConstraint(columnNames={"username"})})
public class User {

    @Id
    @CustomEmailValidator
    @Size.List ({
            @Size(min=5, message="The field must be at least {min} characters"),
            @Size(max=100, message="The field must be less than {max} characters")
    })
    private String username;

    @Basic
    @Column(name = "enabled", columnDefinition = "BIT", length = 1)
    private boolean enabled;

    @JsonManagedReference
    @OneToMany(cascade = {CascadeType.ALL,CascadeType.PERSIST,CascadeType.MERGE}, mappedBy = "user")
    @Column(nullable = false)
    private List<Authority> authorities = new ArrayList<>();
}

Authority.java

@Data
@Entity
@Table(name ="authorities")
public class Authority {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Version
    private Integer version;

    @NotNull
    @Size.List ({
            @Size(min=5, message="The field must be at least {min} characters"),
            @Size(max=100, message="The field must be less than {max} characters")
    })
    private String authority;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "username", nullable=false)
    private User user;
}

One more point if we use Set<> instead of List<> to hold the child objects, we should alter the equals and hash code methods properly as mentioned here - Jackson bug (or feature!?) when using java.util.Set - mySet.size() is always 1

Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
Vijay Muvva
  • 1,063
  • 1
  • 17
  • 31
0

My guess would be that username is never set at all, due to the json unmarshalling or the @CustomEmailValidator failing. If username seems to be set, then it could be that hibernate is trying to persist the user earlier than you expect, before the marhalling or validation has called the username setter.

Try to print the username to the log in setUsername to check if it is set before you get the exception. I would also consider using a @GeneratedValue id in User, like you do in Authority, instead of the @Id on username. That will allow you to check if username can be saved if you remove all constaints, you can always add a unique constraint on the username after debugging..

molholm
  • 1,992
  • 3
  • 25
  • 29
  • I am able to save User entity individually, that means username is set and CustomEmailValidator is working fine. I did ddl print with parameters in hibernate, there are two queries fired in series, first one is to persist the User in which username is set, the other one is to persist the Authority in which username is not set. Not sure what is causing the issue. JSON is setting the username properly in User but as I understand correctly hibernate should set username in Authority as there is a one to many mapping. Please correct me if i'm wrong. – Vijay Muvva Apr 27 '15 at 10:18
  • As far as i know you need to set it in both directions, the JSON unmarshalling does not set user on authorities . I think you have to iterate the authorities on User and call setUser for each authority. – molholm Apr 27 '15 at 10:41
  • Yeah. I also read that we need to set it in both directions. But where should I do that? Where should I write this logic of iterating the Authorities and setting the user in them? Please suggest. Is there a way get this automatically? Why JSON object mapper is unmarshalling this? any idea? – Vijay Muvva Apr 27 '15 at 11:00
  • The JSON object mapper does not know anything about JPA relations, it just looks at getters and setters, but i have seen that Jackson has added some kind support for it with `@JsonManagedReference` and `@JsonBackReference` annotations. Maybe that could solve the problem.. I don't know if they are supported by the default JSON object mapper. – molholm Apr 27 '15 at 12:19
  • @VijayMuvva Peculiarly your solution solved my problem today(http://stackoverflow.com/questions/38056926/exception-jpa-hibernate-detached-entity-passed-to-persist-while-saving-child-m/38057571?noredirect=1#comment63586715_38057571). Is this the only way? – FakirTrappedInCode Jun 28 '16 at 15:00
  • @PondicherryFellow So far, yes. – Vijay Muvva Jun 30 '16 at 03:46