Problema com JPA+Hibernate

6 respostas
worldsoft

Galera é o seguinte, tenho 3 entidades mapeada da seguinte maneira:

Classe User:

@Entity
@Table(name="users")
public class User {		
       //atributos...
	private List<AccessUser> accessUsers = new ArrayList<AccessUser>();

       //getters e setters
	@IndexColumn(name="id")
	@OneToMany(fetch=FetchType.EAGER)	
	@JoinColumn(name="user_login")
	public List<AccessUser> getAccessUsers() {		
		return accessUsers;
	}
	
	protected void setAccessUsers(List<AccessUser> accessUsers) {		
		this.accessUsers = accessUsers;
	}

	public void addAccessUser(AccessUser accessUser){
		if (accessUser != null)
			this.accessUsers.add(accessUser);
	}
}

classe AccessUser:

@Entity
public class AccessUser {					
        //atributos
	private List<UserAccessMenuItem> userAccessMenuItems = new ArrayList<UserAccessMenuItem>();	

        //getters e setters
        @IndexColumn(name="id")
	@OneToMany(fetch=FetchType.EAGER)	
	@JoinColumn(name="accessuser_id")
	public List<UserAccessMenuItem> getUserAccessMenuItems() {		
		return userAccessMenuItems;
	}
	
	public void addUserAccessMenuItem(UserAccessMenuItem userAccessMenuItem){
		if (userAccessMenuItem != null)
			this.userAccessMenuItems.add(userAccessMenuItem);
	}

	protected void setUserAccessMenuItems(List<UserAccessMenuItem> userAccessMenuItems) {		
		this.userAccessMenuItems = userAccessMenuItems;
	}
}

Classe UserAccessMenuItem

@Entity
public class UserAccessMenuItem {
       //Atributoss
	
       //getters e setters
}

O que problema é que quando faço:

user.getAccessUser();

o hibernate está me retornando uma lista assim:

[null, user]

só que executando a sql que o hibernate printa no console e verificando no banco de dados não há valor nulo!

Há algo de errado nesses relacionamentos?

6 Respostas

worldsoft

O mais engraçado é que se eu tirar do método:

a propriedade da anotação

para

funciona.

worldsoft

Alguém sabe como posso resolver?

feltraco

Nao sei se vai resolver.
Mas costumo usar mappedBy em vez de JoinColumn

@OneToMany(cascade=CascadeType.ALL, mappedBy="ordemProducao", orphanRemoval=true)
private List<OrdemProduto> produtosFinalizados;

Tambem utilizo esta annotation:

Para evitar o lazy.

Talvez te ajude.

worldsoft

feltraco:
Nao sei se vai resolver.
Mas costumo usar mappedBy em vez de JoinColumn

@OneToMany(cascade=CascadeType.ALL, mappedBy="ordemProducao", orphanRemoval=true)
private List<OrdemProduto> produtosFinalizados;

Tambem utilizo esta annotation:

Para evitar o lazy.

Talvez te ajude.

Cara infelizmente não funcionou, está gerando o seguinte erro:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'creatorOfSessionFactory': Invocation of init method failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: br.com.tsoftnet.atlas.administration.models.AccessUser.accessuser in br.com.tsoftnet.atlas.administration.models.User.accessUsers at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1413) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425) at br.com.caelum.vraptor.ioc.spring.SpringBasedContainer.start(SpringBasedContainer.java:106) at br.com.caelum.vraptor.ioc.spring.SpringProvider.start(SpringProvider.java:87) at br.com.caelum.vraptor.VRaptor.init(VRaptor.java:110) at br.com.caelum.vraptor.VRaptor.init(VRaptor.java:103) at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:273) at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:254) at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372) at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:98) at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4562) at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5240) at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5235) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: br.com.tsoftnet.atlas.administration.models.AccessUser.accessuser in br.com.tsoftnet.atlas.administration.models.User.accessUsers at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:685) at org.hibernate.cfg.annotations.ListBinder$1.secondPass(ListBinder.java:95) at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:65) at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1689) at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1396) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1829) at br.com.tsoftnet.atlas.infrastructure.CreatorOfSessionFactory.open(CreatorOfSessionFactory.java:31) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:340) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:293) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:130) ... 27 more

Pelo que eu entendi ele está mapeando um atributo chamado accessuser na Classe AccessUser.

feltraco

Sim.
Dentro de UserAccessMenuItem vc deve mapear o outro lado do relacionamento, o ManyToOne.
Algo assim:

@ManyToOne
	@JoinColumn(name = "ordemProducao")
	@ForeignKey(name="FK_ORDEM_PRODUCAO")
	private OrdemProducao ordemProducao;

Se eh a melhor forma nao sei, mas sempre usei assim.
Mapeando os dois lados do relacionamento e usando o MapperdBy.

Att.

worldsoft

Com JPA não há uma solução para esse problema?

Criado 29 de junho de 2011
Ultima resposta 30 de jun. de 2011
Respostas 6
Participantes 2