Error when persisting entity with foreign key field - java

I am try persist in database this entity:
#Entity
#Table(name="pessoa_juridica")
public class PessoaJuridica {
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="cnpj")
#Order(value=1)
private String cnpj;
#Column(name="razao_social")
#Order(value=2)
private String razaoSocial;
#OneToOne( fetch = FetchType.EAGER, cascade = {CascadeType.ALL} )
#Order(value=3)
#JoinColumn(name="contato")
private Contato contato;
}
but when I open the view with the form, I get this error:
org.springframework.beans.NullValueInNestedPathException: Invalid property 'pessoaJuridica.contato' of bean class [com.spring.loja.model.cliente.persistence.model.Cliente]: Could not instantiate property type [java.lang.Integer] to auto-grow nested property path:
java.lang.InstantiationException:
java.lang.Integerorg.springframework.beans.BeanWrapperImpl.newValue(BeanWrapperImpl.java:651)
org.springframework.beans.BeanWrapperImpl.createDefaultPropertyValue(BeanWrapperImpl.java:620)
org.springframework.beans.BeanWrapperImpl.setDefaultValue(BeanWrapperImpl.java:609)
org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:574)
org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:548)
org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:549)
org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:714)
org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:229)
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:120)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:130)org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:120)org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:90)org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)org.apache.jsp.WEB_002dINF.jsp.common.fields_jsp._jspx_meth_form_005flabel_005f13(fields_jsp.java:2969)org.apache.jsp.WEB_002dINF.jsp.common.fields_jsp._jspx_meth_c_005fwhen_005f17(fields_jsp.java:2836)org.apache.jsp.WEB_002dINF.jsp.common.fields_jsp._jspx_meth_c_005fchoose_005f3(fields_jsp.java:2583)org.apache.jsp.WEB_002dINF.jsp.common.fields_jsp._jspx_meth_c_005fforEach_005f4(fields_jsp.java:2539)org.apache.jsp.WEB_002dINF.jsp.common.fields_jsp._jspx_meth_c_005fwhen_005f14(fields_jsp.java:2444)org.apache.jsp.WEB_002dINF.jsp.common.fields_jsp._jspx_meth_c_005fchoose_005f0(fields_jsp.java:242)org.apache.jsp.WEB_002dINF.jsp.common.fields_jsp._jspx_meth_c_005fforEach_005f0(fields_jsp.java:150)org.apache.jsp.WEB_002dINF.jsp.common.fields_jsp._jspService(fields_jsp.java:115)org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:954)org.apache.jsp.WEB_002dINF.jsp.private_.cadastrar_jsp._jspx_meth_form_005fform_005f0(cadastrar_jsp.java:166)org.apache.jsp.WEB_002dINF.jsp.private_.cadastrar_jsp._jspService(cadastrar_jsp.java:88)org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:209)org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267)org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1217)org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952)org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)javax.servlet.http.HttpServlet.service(HttpServlet.java:621)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
the setter/getter methods for Contato are:
public Integer getContato() {
return contato.getId();
}
public void setContato(Integer id) {
this.contato = new Contato(id);
}
the class Contatois this:
#Entity
#Table(name="contato")
public class Contato {
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="nome", unique=true)
#Order(value=1)
private String nome;
#Column(name="email")
#Order(value=2)
private String email;
#Column(name="telefone")
#Order(value=3)
private String telefone;
public Contato() {
this.id = null;
this.nome = null;
this.email = null;
this.telefone = null;
}
public Contato(Integer id) {
this.id = id;
}
}
If I try this for the setter/getter method:
public Contato getContato() {
return contato;
}
public void setContato(Contato contato) {
this.contato = contato;
}
the view is opened, but when I try submit the form, I get the error:
org.hibernate.PersistentObjectException: detached entity passed to persist: com.spring.loja.model.contato.persistence.model.Contatoorg.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:314)org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:432)org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:265)org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:314)org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:432)org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:265)org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)com.spring.loja.config.generic.persistence.Dao.persist(Dao.java:32)com.spring.loja.config.generic.persistence.Dao$$FastClassBySpringCGLIB$$ddbbe880.invoke(<generated>)org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)com.spring.loja.model.cliente.persistence.ClienteHome$$EnhancerBySpringCGLIB$$83cbd101.persist(<generated>)com.spring.loja.config.generic.service.service.cadastra(service.java:45)com.spring.loja.config.generic.service.service$$FastClassBySpringCGLIB$$c92a3159.invoke(<generated>)org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)com.spring.loja.model.cliente.service.ClienteService$$EnhancerBySpringCGLIB$$71ccd54c.cadastra(<generated>)com.spring.loja.config.generic.controller.controller.cadastra(controller.java:42)com.spring.loja.config.generic.controller.controller$$FastClassBySpringCGLIB$$c8cc444b.invoke(<generated>)org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:640)com.spring.loja.model.cliente.controller.ClienteController$$EnhancerBySpringCGLIB$$ffe13d4e_2.cadastra(<generated>)sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)java.lang.reflect.Method.invoke(Method.java:606)org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)javax.servlet.http.HttpServlet.service(HttpServlet.java:647)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
anyone knows the right way to persist the entity?
UPDATE
the field contato is mapped on the view as this:
<form:label path="pessoaJuridica.contato.id" class="label label-default">contato</form:label>
<form:select path="pessoaJuridica.contato.id" class="form-control select embed" data-lista="${url}" data-altera="${altera}" data-remove="${remove}"/>
UPDATE 2
In database, this is the how tables are created:
CREATE TABLE pessoa_juridica
(
id serial NOT NULL,
cnpj character varying(255),
razao_social character varying(255),
contato integer,
CONSTRAINT pessoa_juridica_pkey PRIMARY KEY (id),
CONSTRAINT fk_eaa4oxajsuofatiyag213dio9 FOREIGN KEY (contato)
REFERENCES contato (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE pessoa_juridica
OWNER TO klebermo;
CREATE TABLE contato
(
id serial NOT NULL,
email character varying(255),
nome character varying(255),
telefone character varying(255),
CONSTRAINT contato_pkey PRIMARY KEY (id),
CONSTRAINT uk_rrtn7wgfxo0jfwkhby23f72cn UNIQUE (nome)
)
WITH (
OIDS=FALSE
);
ALTER TABLE contato
OWNER TO klebermo;

As I remember, the join column name is not the name of the object you are joining to, but the name of the column on the object you are joining to.

You told JPA to cascade all! and passed detached object to save, that is an issue.
According to Hibernate.
CascadeType.PERSIST: cascades the persist (create) operation to
associated entities persist() is called or if the entity is managed
You said #OneToOne( fetch = FetchType.EAGER, cascade = {CascadeType.ALL} ) means it will apply all Transitive persistence.
So removing cascade = {CascadeType.ALL} will solve the prob.
#OneToOne( fetch = FetchType.EAGER)
#Order(value=3)
#JoinColumn(name="contato")
private Contato contato;

Related

How to avoid duplicate insertions of "many" entity in one-to-many relationship when using a unique constraint in eclipselink/JPA

I am working on a large codebase using Spring MVC with EclipseLink 2.5.2 on a mysql database. The database and its structure are created directly, not through any code-first approach. My problem concerns 2 tables in a one-to-many relationship.
CREATE TABLE ROLE (
ID BIGINT(20) PRIMARY KEY,
-- OTHER FIELDS --
);
CREATE TABLE ROLE_DOMAIN (
ID BIGINT(20) PRIMARY KEY,
ROLE_ID BIGINT(20) NOT NULL,
DOMAIN VARCHAR(255) NOT NULL
-- OTHER FIELDS --
);
ALTER TABLE ROLE_DOMAIN ADD CONSTRAINT FK_ROLE_DOMAIN_ROLE_ID FOREIGN KEY (ROLE_ID) REFERENCES ROLE_BASE (ID) ON DELETE CASCADE;
ALTER TABLE ROLE_DOMAIN ADD CONSTRAINT UQ_ROLE_DOMAIN_ROLE_ID_DOMAIN UNIQUE (ROLE_ID, DOMAIN);
And in java, this is how I've got the two entities configured.
#Entity
public class Role {
private Long id;
private Set<RoleDomain> roleDomains = new HashSet<>();
#Id
#TableGenerator(name = "ROLE.ID", allocationSize = 1, initialValue = 1)
#GeneratedValue(strategy = GenerationType.TABLE, generator = "ROLE.ID")
public Long getID() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name = "ROLE_ID", referencedColumnName = "ID", insertable = false, updatable = false)
public Set<RoleDomain> getRoleDomains() {
return roleDomains;
}
public void setRoleDomains(Set<RoleDomain> roleDomains) {
this.roleDomains = roleDomains;
}
}
#Entity
#Table(name = "ROLE_DOMAIN")
public class RoleDomain {
private Long id;
private Long roleId;
private String domain;
#Id
#TableGenerator(name = "ROLE_DOMAIN.ID", allocationSize = 1, initialValue = 1)
#GeneratedValue(strategy = GenerationType.TABLE, generator = "ROLE_DOMAIN.ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "ROLE_ID", nullable = false)
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
#Column(name = "DOMAIN", length = 255)
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
}
Say that in this table structure, I already have a record in ROLE and a record in ROLE_DOMAIN that references it, translating to a Role object named myRole containing the RoleDomain in roleDomains.
Now, when I add a new RoleDomain and save using a spring data repository like this:
myRole.add(new RoleDomain("some string"));
roleRepository.save(myRole);
I get an exception for a duplicate insert violating my unique constraint on ROLE_ID and DOMAIN in the database.
[EL Warning]: 2020-10-22 14:53:22.405--UnitOfWork(994047815)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.8.v20190620-d6443d8be7): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '198732-some string' for key 'UQ_ROLE_DOMAIN_ROLE_ID_DOMAIN'
Error Code: 1062
Call: INSERT INTO ROLE_DOMAIN (ID, DOMAIN, ROLE_ID) VALUES (?, ?, ?)
bind => [27, some other string, 198732]
The weirdest thing about this problem is that if I remove the unique constraint from the database (Note: keeping the java annotation configuration EXACTLY the same. Literally just "DROP CONSTRAINT..." in the db) then the save call works just fine. It doesn't create duplicates in ROLE_DOMAIN. It does exactly what it's supposed to, just adds the new record to ROLE_DOMAIN.
I don't understand how a unique constraint in the db would cause eclipselink to act this inconsistently. Do I have something configured wrongly? Thanks.
EDIT:
I have just now tried replacing the #Table annotation on the RoleDomain class with this:
#Table(name = "ROLE_DOMAIN", uniqueConstraints =
#UniqueConstraint(columnNames = {"ROLE_ID", "DOMAIN"}))
It didn't change anything.
The issue with your constraint is that EclipseLink orders statements for batching, putting deletes last - this is to give you a chance to clean up other constraints, to modify existing rows before rows get deleted. This can be changed so that deletes are issued first using the setShouldPerformDeletesFirst method on the UnitOfWork. As this is native api, you will have to unwrap the EntityManager to get at it, using
em.unwrap(org.eclipse.persistence.sessions.UnitOfWork.class)
if you are in a transaction. This will only be set for the UnitOfWork within this EntityManager, so if you need it everywhere always, you will want to have a session listener with your own session adaptor class to listen for postAcquireUnitOfWork and call setShouldPerformDeletesFirst on it.

Cannot add or update a child row: a foreign key constraint fails MySQL Hibernate

It seems to be a common error. I've seen other topics, but nothing changed. Here is MySQL script:
DROP DATABASE IF EXISTS `library`;
CREATE DATABASE IF NOT EXISTS `library`;
USE `library`;
SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT;
SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS;
SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION;
SET NAMES utf8;
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
SET #OLD_SQL_NOTES=##SQL_NOTES, SQL_NOTES=0;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE customer
(
c_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
first_name CHAR(50) NOT NULL,
last_name CHAR(50) NOT NULL,
email CHAR(50) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO customer VALUES
(1,'David','Bush','bushd#gg.com'),
(2,'John','Doe','johnd#gg.com'),
(3,'Max','Rao','maxr#gg.com'),
(4,'Mary','James','maryj#gg.com'),
(5,'Tony','Lord','tony#gg.com');
CREATE TABLE rental
(
rental_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
issue_date DATE,
return_date DATE,
customer_id INT,
book_id INT,
KEY `FK_CUSTOMER_idx` (`customer_id`),
CONSTRAINT `FK_CUSTOMER`
FOREIGN KEY (`customer_id`)
REFERENCES `customer` (`c_id`),
KEY `FK_BOOK_idx` (`book_id`),
CONSTRAINT `FK_BOOK`
FOREIGN KEY (`book_id`)
REFERENCES `book` (`b_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO rental VALUES
(1,'2014-10-11',null,3,1),
(2,'2014-10-11',null,5,2);
CREATE TABLE book
(
b_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
author CHAR(50) NOT NULL,
title CHAR(100) NOT NULL,
category CHAR(50) NOT NULL,
availability CHAR(5) NOT NULL DEFAULT 'yes'
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO book VALUES
(1,'Doyle','The adventures of binkle and flip','Child','no'),
(2,'Blyton','The adventures of sherlock holmes','Crime fiction','no'),
(3,'Rustard','Insects','Science','yes'),
(4,'Larsson','Man who hate woman','Crime','yes'),
(5,'Tolkien','Lord of the Rings: The Two Towers','Fantasy','lost');
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
SET CHARACTER_SET_CLIENT=#OLD_CHARACTER_SET_CLIENT;
SET CHARACTER_SET_RESULTS=#OLD_CHARACTER_SET_RESULTS;
SET COLLATION_CONNECTION=#OLD_COLLATION_CONNECTION;
SET SQL_NOTES=#OLD_SQL_NOTES;
SET FOREIGN_KEY_CHECKS=1;
Here is the error:
ERROR: Cannot add or update a child row: a foreign key constraint fails
(`library`.`rental`, CONSTRAINT `FK_BOOK` FOREIGN KEY (`book_id`) REFERENCES
`book` (`b_id`))
Rental entity:
#Entity
#Table(name="rental")
public class Rental {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="rental_id")
private int id;
#Column(name="issue_date")
private Date issueDate;
#Column(name="return_date")
private Date returnDate;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name="book_id", referencedColumnName="b_id")
private Book book;
#ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name="customer_id", referencedColumnName="c_id")
private Customer customer;
Customer entity:
#Entity
#Table(name="customer")
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="c_id")
private int id;
#NotNull
#Column(name="first_name")
private String firstName;
#NotNull
#Column(name="last_name")
private String lastName;
#Email
#Column(name="email")
private String email;
#OneToMany(mappedBy="customer")
private List<Rental> rentals;
Book entity:
#Entity
#Table(name="book")
public class Book {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="b_id")
private int id;
#NotNull
#Column(name="author")
private String author;
#NotNull
#Column(name="title")
private String title;
#NotNull
#Column(name="category")
private String category;
#NotNull
#NotEmpty
#Column(name="availability")
private String availability;
#OneToMany(mappedBy="book")
private List<Rental> rentals;
Controller(values hardcoded for testing):
#PostMapping("/confirmRent")
public String confirmRent(/*PathVariable ("customerId") int cId,
#PathVariable ("bookId") int bId*/) {
int cId = 5;
int bId = 5;
Customer theCustomer = customerService.getCustomer(cId);
Book theBook = bookService.getBook(bId);
rentalService.createNewEntry(theCustomer, theBook);
return "redirect:/book/allAvailableBooks";
}
DAO :
#Override
public void createNewEntry(Customer theCustomer, Book theBook) {
Session currentSession = sessionFactory.getCurrentSession();
Rental rental = new Rental();
rental.setBook(theBook);
rental.setCustomer(theCustomer);
currentSession.save(rental);
}
Am I missing something out? PS: The code may look amateurish: I'm a beginner ;)

JPA Entitties, how to join tables

I have three tables
CREATE TABLE "ingredient" (
"id" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY,
"ingredient" VARCHAR(50) NOT NULL
);
CREATE TABLE "pizza" (
"id" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY,
"pizza" VARCHAR(50) NOT NULL
);
CREATE TABLE "pizza_structure" (
"pizza_id" INT NOT NULL,
"ingredient_id" INT NOT NULL,
"amount" INT NOT NULL
);
how to join them, to get Pizzas structure as a Map
#Entity
#Table(name = "ingredient")
public class Ingredient{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public Ingredient() {
}
}
#Entity
#Table(name = "pizza")
public class Pizza {
#Id
#GeneratedValue
private Long id;
private String name;
#OneToMany ????
private Map<Ingredient, Integer> pizzaStructure;
public Pizza() {
}
public Pizza(String name, Map<Long, Integer> pizzaStructure) {
this.name = name;
this.pizzaStructure = pizzaStructure;
}
}
do I need to create #Embeddable class PizzaStructure, if yes when how to use it?
now I'm getting an error
Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class:
how to join them, to get Pizzas structure as a Map
It seems to look like this:
#ElementCollection
#CollectionTable(name = "pizza_structure", joinColumns = {#JoinColumn(name = "pizza_id")})
#Column(name = "amount")
#MapKeyJoinColumn(name = "ingredient_id")
private Map<Ingredient, Integer> pizzaStructure;
do I need to create #Embeddable class PizzaStructure
No.
More info is here: Hibernate User Guide - Maps.
Note that table pizza_structure should have foreign keys to pizza and ingredient tables and also unique constrain of pizza_id and ingredient_id, like this (it's postgresql dialect):
create table pizza_structure
(
pizza_id ... constraint fk_structure_pizza references pizza,
ingredient_id ... constraint fk_structure_ingredient references ingredient,
amount ...,
constraint pizza_structure_pkey primary key (pizza_id, ingredient_id)
);
You have a manyToMany relationship between pizza and ingredient and an additional column in your relationship.
I found a similar question here: JPA 2.0 many-to-many with extra column
(I would comment, but i do not have enough reputation.)

How to make a reflexive one-to-many relationship inside a model?

In the database there is a table having a reflexive one-to-many relationship :
create table structure
(
struct_code varchar2(15) not null,
str_struct_code varchar2(15),
struct_lib varchar2(255),
struct_sigle varchar2(10),
struct_comment clob,
struct_interne smallint default 1,
constraint pk_structure primary key (struct_code)
);
alter table structure add constraint fk_structur_associati_structur foreign key (str_struct_code) references structure (struct_code);
I created the corresponding model :
#Entity
#Table(name = "structure")
public class Structure {
#Id()
#Column(name="struct_code")
private String code;
#Column(name="struct_sigle")
private String sigle;
#Column(name="struct_lib")
private String lib;
#Column(name="struct_interne")
private Integer interne;
#ManyToOne
#JoinColumn(name = "struct_code")
private Structure sousStructure;
public Structure() {
super();
}
public Structure(String code) {
super();
}
// getters and setters
}
But when I built the project then I got the error : mappingexception repeated column in mapping for entity : com.ambre.pta.model.Structure column: struct_code (should be mapped with insert="false" update="false")
So how to write correctly the reflexive relation ?
I do have something like this in place:
#ManyToOne
#JoinColumn(name = "parent_struct_code", nullable = true)
private Structure parentStructure;
#OneToMany(mappedBy = "parentStructure", cascade = CascadeType.REMOVE, fetch=FetchType.LAZY)
private List<Structure> sousStructures = new ArrayList<>();

saving of entity in the database causes unexpected behaviors

When I try persist the entity below in the database, in a application which uses spring and hibernate, in the way it's presented, I get the error object references an unsaved transient instance - save the transient instance before flushing; but if I add the value cascade = CascadeType.ALL to the annotation #OneToOne (or add the annotation #Cascade), for each attribute I don't fill it's inserted an empty record in the database.
#Entity
#Table(name="cliente")
public class Cliente {
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="usuario")
#Order(value=1)
private Usuario usuario;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="pessoa_fisica")
#Order(value=2)
private PessoaFisica pessoaFisica;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="pessoa_juridica")
#Order(value=3)
private PessoaJuridica pessoaJuridica;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="endereco_entrega")
#Order(value=4)
private Endereco endereco_entrega;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="endereco_cobranca")
#Order(value=5)
private Endereco endereco_cobranca;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name="pedidos_do_cliente", joinColumns={#JoinColumn(name="fk_cliente")}, inverseJoinColumns={#JoinColumn(name="fk_pedido")})
#Order(value=6)
private List<Pedido> pedido;
}
Anyone can tell me how to fix this problem?
ps.: below the related method which handle this process:
controller
#RequestMapping(value="cadastra", method=RequestMethod.POST)
#ResponseBody
public String cadastra(#ModelAttribute("object") E object, BindingResult result, #RequestParam(value="file", required=false) MultipartFile file, #RequestParam(value="icone", required=false) MultipartFile icone) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
serv.cadastra(object);
serv.upload_picture(object, file, "picture");
serv.upload_picture(object, icone, "icone");
return "";
}
service
#Transactional
public void cadastra(E e) {
dao.persist(e);
}
dao class
#Transactional
public void persist(E transientInstance) {
sessionFactory.getCurrentSession().persist(transientInstance);
}
UPDATE
CREATE TABLE cliente
(
id serial NOT NULL,
endereco_cobranca integer,
endereco_entrega integer,
pessoa_fisica integer,
pessoa_juridica integer,
usuario integer,
CONSTRAINT cliente_pkey PRIMARY KEY (id),
CONSTRAINT fk_4taj5h8hxci6slrw0n3d336i7 FOREIGN KEY (endereco_entrega)
REFERENCES endereco (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_7a5l0l5enj00apelvmcdatkmm FOREIGN KEY (pessoa_juridica)
REFERENCES pessoa_juridica (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_iiibo76b56caciax4yl0jo0m6 FOREIGN KEY (pessoa_fisica)
REFERENCES pessoa_fisica (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_lwavy2v0wb0vmxisg7hbe3mbu FOREIGN KEY (usuario)
REFERENCES usuario (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_r2pyppeltv7xoe5quenf2l1gd FOREIGN KEY (endereco_cobranca)
REFERENCES endereco (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE cliente
OWNER TO klebermo;
In your view layer, are you creating new objects for the these linked columns? or in the controller that serves the form, are you adding 'new' objects to the model? It seems as though you have created empty java objects for these one-to-one columns which is why you cant save the parent without saving the children and why with cascade option it creates empty records.

Categories