• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Save and Delete Bidirectional Foreign key entities

 
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I am using a User, Role and UserRole class with bidirectional relationship. I am not able to save or delete userrole object in database. Here are the classes

User.java


Role.java

UserRole.java


I am using angularjs (front end) to communicate with spring-data-jpa(backend) to perform save and delete operations. I tried saving the id's of user and role directly into db but it throws an exception

ERROR: org.springframework.data.rest.webmvc.AbstractRepositoryRestController - not-null property references a null or transient value : com.ellora.collorado.model.UserRole.employee; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.ellora.collorado.model.UserRole.employee
org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value : com.ellora.collorado.model.UserRole.employee; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.ellora.collorado.model.UserRole.employee
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:207)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:155)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:111)
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.$Proxy82.save(Unknown Source)
at org.springframework.data.rest.core.invoke.CrudRepositoryInvoker.invokeSave(CrudRepositoryInvoker.java:106)
at org.springframework.data.rest.webmvc.RepositoryEntityController.createAndReturn(RepositoryEntityController.java:414)
at org.springframework.data.rest.webmvc.RepositoryEntityController.postCollectionResource(RepositoryEntityController.java:232)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
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:111)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:799)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:728)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
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.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
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.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
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:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)



So I fetched both the objects using the id's and then tried to store them, there was no exception but the values weren't stored in database. Same is the case for delete. Kindly help me.

Regards
Parthe
 
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Probably a similar issue as in your other bidirectional issue.

When you have a bidirectional association, it's your responsibility to make the changes at both sides to ensure that your object model is consistent. So you can't delete an object by only its id.
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Roel,

For delete, its ok but I am struggling with add for about a week now . Today I tried something similar in add like what you instructed me for delete but I am not able to bring the object from angularjs to Spring data jpa. Usually what we do is pass the id in url but I think we won't be able to pass an object in url. Help me out here please
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can you explain why class Role has a UserRole collection? That makes no sense at all. But that's probably because you have a bidirectional relationship. Having bidirectional relationships complicate your model (and code) as you already experienced the past week. So I would only use them when it has some added value. Don't use bidirectional relationships by default as it will probably result in more complex code without any added value.

Here you'll find some examples of many-to-many relationships. Look especially to the Advanced section, it is very similar to your use case (ProjectAssociation = UserRole)
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Roel,

As I told you earlier this code was given to me by my seniors, I am new here. Say If I remove Set<UserRole> from Role class it would become Unidirectional and what about Employee then? Will I have to remove bidirectional there too? In case that solves the problem, I am ready to give it a try.

I tried as per the example provided is the advanced section as you have mentioned but I am not able to take it further. Two things are interrupting

1) If I comment out my Id field in UserRole(ProjectAssociation in the example), I am not able to run the project as the id field is associated with several other modules.

2) Even if I some how manage to run the project, I have only the ID's. I can call the Role(Project).addEmployee(Employee employee) method by passing the id's to a function in java controller and then call it. I don't think that is preferred. Correct me if I am wrong.
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Partheban Udayakumar wrote:As I told you earlier this code was given to me by my seniors,


So I assume you could ask your seniors for advice. They probably use a model they are familiar with and already have experience with saving/deleting data using a similar model.

Partheban Udayakumar wrote:2) Even if I some how manage to run the project, I have only the ID's. I can call the Role(Project).addEmployee(Employee employee) method by passing the id's to a function in java controller and then call it. I don't think that is preferred. Correct me if I am wrong.


Using a bidirectional relationship, it's your responsibility to make the changes at both sides to ensure that your object model is consistent. That's really important.

So I would expect you'll have some method likeAnd then in Employee and Role you have a addUserRole method like

Hope it helps!
Kind regards,
Roel
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Roel,

I tried your example but I think there is some mistake in what I do with angularjs part. I have implemented the solution in UserRoleServiceImplementation and have called it from UserRoleController using angularjs but it says POST method not supported and the userrole doesn't add. Here is what I tried for calling UserRoleController from angular js

controller.js


services.js



UserRoleController.java



Here is the output it shows

WARN : org.springframework.web.servlet.PageNotFound - Request method 'POST' not supported

 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A nice overview of all involved code but the most important part is missing: the actual url to which the POST request is sent...
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Roel,

Actual url?? I don't get it. From the controller.js "UserRole.saveUserRole()", it goes to services.js "saveUserRole: {method: 'POST', url: appConfig.apiRootPath + 'userRoles/:userId/:roleId/add'}" and then this calls UserRoleController's "@RequestMapping(value = "/{userId}/{roleId}/add", method = POST)". This is the flow, I have been taught. If you want the full url that is called, its "localhost:8080/#/api/userRoles/25/2/add"

I forgot to mention that UserRoleController has this,



and btw UserRole delete works fine, thanks for that too.
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Partheban Udayakumar wrote:If you want the full url that is called, its "localhost:8080/#/api/userRoles/25/2/add"


That was indeed what I was looking for If that url is wrong, you can do whatever changes you want to your backend but it won't work. But the url looks ok! And your request-mapping should match with that url.

But the saveUserRole method in UserRole (services.js) defines userRole (not userRoles) in the url. But in your last post, it defines userRoles. So I assume you have already made some changes.

With the current code, I would think the addUserRole method in UserRoleController will be executed if you perform a POST-request to url "localhost:8080/#/api/userRoles/25/2/add". Did you already try setting the debug level of your application to DEBUG? Then you get more info about the different controllers (and paths) Spring MVC tries to match your url against.

And maybe you could use Postman (from Chrome Web Store) for debugging purposes. I use it myself as well to quickly execute some test requests (get, post,...) with or without payload, with or without headers. It's a very powerful tool.
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Roel,

Ya. I have added the 's' as you have mentioned but I am not able to add still. I don't know about setting my app to DEBUG level, could you please brief me about it?? I will definitely try postman

EDIT 1: I tried Postman, it gives me only the 405 report. I am not able to figure out any thing from that.
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Partheban Udayakumar wrote:EDIT 1: I tried Postman, it gives me only the 405 report. I am not able to figure out any thing from that.


405 = method not allowed

So you have an url which accepts e.g. a POST request and you are sending a GET request instead...
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Partheban Udayakumar wrote:I don't know about setting my app to DEBUG level, could you please brief me about it??


It all depends on which logging framework you are using...
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roel De Nijs wrote:
405 = method not allowed

So you have an url which accepts e.g. a POST request and you are sending a GET request instead...



This is clear from the eclipse console warning which I had provided. I have method = POST in UserRoleController and in service, I use method: 'POST' but I don't know how it mismatches??

Roel De Nijs wrote:
It all depends on which logging framework you are using...



I don't even know the basics of debugging, could you please provide me a link where I can start about debugging?? As for logging framework, I am using the Log4j (1.6.6)
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If your request doesn't enter the method defined in your controller, it's very hard to debug. That's why setting the log level to DEBUG only for spring mvc classes will give you some info about the url to request mapping matching process.

As you are using log4j, you'll have a log4j.properties file somewhere. So just addor you could just set the rootLogger level to DEBUG. Here and here (if you have log4 xml config file) you'll find more info. And I'm pretty sure your seniors will be happy to learn you how to change the logging level of your application to retrieve valuable information.
 
Partheban Udayakumar
Ranch Hand
Posts: 499
Spring AngularJS Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Roel,

I tried debugging as you said but nothing appears in my eclipse console when I call UserRole.save() function. What does this mean? No request is sent using the model? If so how can I solve this?
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Partheban Udayakumar wrote:I tried debugging as you said but nothing appears in my eclipse console when I call UserRole.save() function. What does this mean? No request is sent using the model? If so how can I solve this?


The main question still is: you have a method in your UserRoleController to add a user role. If you add a user role in the front-end, does your program enter the appropriate method of the UserRoleController class?
 
Seriously Rick? Seriously? You might as well just read this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic