Duvida Hibernate annotation [RESOLVIDO]

9 respostas
B

Bom dia.
Pessoal estou com algumas duvidas com o hibernate annotation. Já procurei no google e em varios foruns porém ainda não entendi como faço pra mapear um ManyToMany.

Eu tenho usuario e Permissão, onde o usuario tem varias permissoes e a permissão tem varios usuarios criando uma nova entidade usuarioPermisão

as classes ficariam assim:

public class usuario {

private int idUsuario;

...

}
public class permissao {

private int idPermissao;

...

}

E a 3 entidade

public class usuarioPermissao {

private int idUsuario;
private int idPermissao;


...

}

Como ficaria as anotações nessas classes?

Obrigado

9 Respostas

D

Se você não precisar de nenhum atributo dentro da classe de ligação entre as entidades, você não precisa criar a classe.
Ficaria algo como:

@Entity
public class Usuario {
    
    @Id
    @GeneratedValue
    private long id;

    // o lado forte da relação é o usuário que tem as permissões
    @ManyToMany
    private Set<Permissao> permissoes;

}

@Entity
public class Permissao {
    
    @Id
    @GeneratedValue
    private long id;

    // permissão tem o lado fraco do relacionamento, sendo 
    // referenciada pelo atributo permissoes da entidade Usuario
    @ManyToMany( references = "permissoes" )
    private Set<Usuario> usuarios;

}

[]´s

B

Então eu fiz o seguinte:

@Entity
@Table(name="user")
public class User implements br.com.conrado.j4b.domain.Entity {

	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)  	
	private Long identity;
	private String name;
	private String login;
	private String password;	
	private Date dateRegister;
	
	@ManyToMany
	private List<Permissions> permissions;

}

@Entity
@Table(name="permissions")
public class Permissions implements br.com.conrado.j4b.domain.Entity {
	
	private Long identity;
	private String robotName;		
	@ManyToMany(mappedBy="permissions")  
	private List<User> users;

}

Mais da o sguinte erro:

SEVERE: Exception sending context initialized event to listener instance of class br.com.mercadolivre.robot.servlet.RobotContextListener
org.hibernate.HibernateException: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: permissions, for columns: [org.hibernate.mapping.Column(responsiblesPermitions)]
	at br.com.mercadolivre.robot.config.Application.getSessionFactory(Application.java:32)
	at br.com.mercadolivre.robot.servlet.RobotContextListener.contextInitialized(RobotContextListener.java:62)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3934)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4429)
	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
	at org.apache.catalina.core.StandardHost.start(StandardHost.java:722)
	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
	at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
	at org.apache.catalina.core.StandardService.start(StandardService.java:516)
	at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:583)
	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.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: permissions, for columns: [org.hibernate.mapping.Column(responsiblesPermitions)]
	at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:269)
	at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:253)
	at org.hibernate.mapping.Property.isValid(Property.java:185)
	at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:440)
	at org.hibernate.mapping.RootClass.validate(RootClass.java:192)
	at org.hibernate.cfg.Configuration.validate(Configuration.java:1108)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1293)
	at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
	at br.com.mercadolivre.robot.config.Application.getSessionFactory(Application.java:26)
	... 16 more
11/02/2010 11:40:19 org.apache.catalina.core.StandardContext start
SEVERE: Error listenerStart
A

Substitua o List por Set!

O List diferentemente do Set, permite que existam objetos repetidos, por isso o hibernate diz em sua referencia que o ideal seria utilizar Set.

B

Continua o erro:

org.hibernate.HibernateException: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: user, for columns: [org.hibernate.mapping.Column(permissions)]
	at br.com.mercadolivre.robot.config.Application.getSessionFactory(Application.java:32)
	at br.com.mercadolivre.robot.test.FlagRepositotyTest.setup(FlagRepositotyTest.java:17)
	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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
	at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: user, for columns: [org.hibernate.mapping.Column(permissions)]
	at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:269)
	at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:253)
	at org.hibernate.mapping.Property.isValid(Property.java:185)
	at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:440)
	at org.hibernate.mapping.RootClass.validate(RootClass.java:192)
	at org.hibernate.cfg.Configuration.validate(Configuration.java:1108)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1293)
	at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
	at br.com.mercadolivre.robot.config.Application.getSessionFactory(Application.java:26)
	... 24 more
A

Não se ofenda!

Seu objeto segue o padrão javabean de gets e sets para os atributos?

A

Você esta notando o identificador com @Id da Entidade Permissions?

B

Bom vou colocar aqui as classes como estão… Segue sim o padão e tem as anotações de @Id, @entity

A classe permissions:

@Entity
@Table(name="permissions")
public class Permissions implements br.com.conrado.j4b.domain.Entity {

	private Long identity;
	private String robotName;	
	private Set<Responsible> responsibles;
	

	public Permissions() {
		this.responsibles = new HashSet<Responsible>();
	}

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getIdentity() {
		return identity;
	}

	public void setIdentity(Long identity) {
		this.identity = identity;
	}

	public String getRobotName() {
		return robotName;
	}

	public void setRobotName(String robotName) {
		this.robotName = robotName;
	}

	public void addResponsiblePermissions(Responsible responsiblePermission) {
		this.responsibles.add(responsiblePermission);
	}

	public void removeResponsiblePermissions(Responsible responsiblePermission) {
		this.responsibles.remove(responsiblePermission);
	}		

	@ManyToMany(
			cascade={CascadeType.PERSIST, CascadeType.MERGE},
			mappedBy="permissions",
			targetEntity=Responsible.class
	)
	public Set<Responsible> getResponsibles() {
		return this.responsibles;
	}

	@Override
	public int hashCode() {
		return  this.identity.hashCode();	
	}

	@Override
	public boolean equals(Object obj) {		
		return obj instanceof Permissions && this.equals((Permissions)obj);
	}

	private boolean equals(Permissions other) {		
		return this.identity.equals(other.identity);
	}
}

Classe Responsible refere-se ao usuario

@Entity
@Table(name="responsible")
public class Responsible implements br.com.conrado.j4b.domain.Entity {


	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)  	
	private Long identity;
	private String name;
	private String login;
	private String password;
	private String passwordString;
	private Date dateRegister;
	private Set<Permissions> permissions;	


	public Responsible() {
		this.permissions = new HashSet<Permissions>();
	}		
	
	public Long getIdentity() {
		return identity;
	}

	public void setIdentity(Long identity) {
		this.identity = identity;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	@Transient
	public String getPasswordString() {		
		return passwordString;
	}

	public void setPasswordString(String passwordString) {
		this.passwordString = passwordString;
	}

	@Temporal(value=TemporalType.TIMESTAMP)
	public Date getDateRegister() {
		return dateRegister;
	}

	public void setDateRegister(Date dateRegister) {
		this.dateRegister = dateRegister;
	}

	public void addResponsablePermissions(Permissions userPermission) {
		this.permissions.add(userPermission);
	}

	public void removeResponsablePermissions(Permissions userPermission) {
		this.permissions.remove(userPermission);
	}

	@ManyToMany(
			targetEntity=Permissions.class,
			cascade={CascadeType.PERSIST, CascadeType.MERGE}
	)
	@JoinTable(
			name="responsiblepermissions",
			joinColumns={@JoinColumn(name="responsibleidentity")},
			inverseJoinColumns={@JoinColumn(name="permissionsidentity")}
	)	
	public Set<Permissions> getPermissions() {
		return this.permissions;
	}
 
	@Override
	public int hashCode() {
		return  this.identity.hashCode();	
	}

	@Override
	public boolean equals(Object obj) {		
		return obj instanceof Responsible && this.equals((Responsible)obj);
	}

	private boolean equals(Responsible other) {		
		return this.identity.equals(other.identity);
	}	
}

e a minha classe que seria a associativa:

@Entity
@Table(name="responsiblepermissions")
public class ResponsiblePermissions implements br.com.conrado.j4b.domain.Entity {


	private Long identity;
	private Long responsibleIdentity;
	private Long permissionsIdentity;
	
	public Long getIdentity() {
		return identity;
	}
	
	public void setIdentity(Long identity) {
		this.identity = identity;
	}
	
	public Long getResponsibleIdentity() {
		return responsibleIdentity;
	}
	
	public void setResponsibleIdentity(Long responsibleIdentity) {
		this.responsibleIdentity = responsibleIdentity;
	}
	
	public Long getPermissionsIdentity() {
		return permissionsIdentity;
	}
	
	public void setPermissionsIdentity(Long permissionsIdentity) {
		this.permissionsIdentity = permissionsIdentity;
	}
	
	
	
}

Verifiquei a documentação do annotation e cheguei a esse codigo.

Alguem sabe me informar oq esta de errado?

Obrigado

B

Alguma ideia?

Obrigado

B

Então percebi que quando temos uma entidade associativa e nessa entidade só temos as chaves estrangeiras usamos o ManyToMany, caso tenha algum campo diferente das chaves estrangeiras na associativa usamos o ManyToOne e OneToMany respectivamente.

Bom meu caso era o ManyToMany, então não preciso de uma classe associativa, no meu caso ResponsiblePermissions. Em fim, o erro era esse:

org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: responsible, for columns: [org.hibernate.mapping.Column(permissions)]

O que acontece é que no mapeamento de minha classe a anotação @Id estava no get e o hibernate não encontrava a chave de minha classe então resolvi apenas colocando o @Id no meu campo chave privado. Segue as classes como ficaram:

Classe Permission

package br.com.mercadolivre.robot.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;


@Entity
@Table(name="permission") 
public class Permission implements br.com.conrado.j4b.domain.Entity {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long identity;
	private String robotName;
	
	@ManyToMany(fetch = FetchType.LAZY)  
	@JoinTable(
				name = "responsiblepermissions", 				
				joinColumns = { 
							@JoinColumn(
										name = "permissionsIdentity",
										nullable = false,  
										updatable =  false) }, 
	 			inverseJoinColumns = {  
							@JoinColumn(
										name = "responsibleIdentity", 
										nullable = false, 
										updatable = false) }
	)  
	private Set<Responsible> responsibles = new HashSet<Responsible>();
	

	
	public Long getIdentity() {
		return identity;
	}

	public void setIdentity(Long identity) {
		this.identity = identity;
	}

	public String getRobotName() {
		return robotName;
	}

	public void setRobotName(String robotName) {
		this.robotName = robotName;
	}

	/*public void addResponsiblePermissions(ResponsiblePermissions responsiblePermission) {
		this.responsibles.add(responsiblePermission);
	}

	public void removeResponsiblePermissions(ResponsiblePermissions responsiblePermission) {
		this.responsibles.remove(responsiblePermission);
	}*/		

	public Set<Responsible> getResponsibles() {
		return this.responsibles;
	}

	@Override
	public int hashCode() {
		return  this.identity.hashCode();	
	}

	@Override
	public boolean equals(Object obj) {		
		return obj instanceof Permission && this.equals((Permission)obj);
	}

	private boolean equals(Permission other) {		
		return this.identity != null && this.identity.equals(other.identity);
	}
}

Classe Responsible

package br.com.mercadolivre.robot.domain;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;


@Entity
@Table(name="responsible")
public class Responsible implements br.com.conrado.j4b.domain.Entity {


	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)  	
	private Long identity;
	private String name;
	private String login;
	private String password;
	private String passwordString;
	private Date dateRegister;
	@ManyToMany(fetch = FetchType.LAZY)  
	@JoinTable(
				name = "responsiblepermissions", 				
				joinColumns = { 
							@JoinColumn(
										name = "responsibleIdentity",
										nullable = false,  
										updatable =  false) }, 
	 			inverseJoinColumns = {  
							@JoinColumn(
										name = "permissionsIdentity", 
										nullable = false, 
										updatable = false) }
	)  
	private Set<Permission> permissions = new HashSet<Permission>();	
		
	
	public Long getIdentity() {
		return identity;
	}

	public void setIdentity(Long identity) {
		this.identity = identity;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	@Transient
	public String getPasswordString() {		
		return passwordString;
	}

	public void setPasswordString(String passwordString) {
		this.passwordString = passwordString;
	}

	@Temporal(value=TemporalType.TIMESTAMP)
	public Date getDateRegister() {
		return dateRegister;
	}

	public void setDateRegister(Date dateRegister) {
		this.dateRegister = dateRegister;
	}

	/*public void addResponsablePermissions(Permission userPermission) {
		this.responsiblesPermissions.add(userPermission);
	}

	public void removeResponsablePermissions(Permission userPermission) {
		this.responsiblesPermissions.remove(userPermission);
	}*/
	
	public Set<Permission> getPermissions() {
		return this.permissions;
	}
 
	@Override
	public int hashCode() {
		return  this.identity.hashCode();	
	}

	@Override
	public boolean equals(Object obj) {		
		return obj instanceof Responsible && this.equals((Responsible)obj);
	}

	private boolean equals(Responsible other) {		
		return this.identity.equals(other.identity);
	}	
}

Se eu estiver errado em alguma coisa que escrevi, por favor, me fale par que eu tenha em mente o que é certo e não cometa erros.

Obrigado

Criado 11 de fevereiro de 2010
Ultima resposta 15 de fev. de 2010
Respostas 9
Participantes 3