Erro no mapeamento Hibernate

1 resposta
B

Pessoal Bom dia

Tenho a seguinte situação:

tenho uma entidade chamada menu onde eu agrupo outras entidades do tipo funcionalidade e para isso tenho uma tabela no meio de menu e funcionalidade(que foi mapeada e o prórpio Hibernate criou para mim).

Meu sistema funciona com permissões ou seja só vou carregar menus.funcionalidades se o usuário tiver permissão para este acesso.
Para isso criei uma entidade chamada permissão onde eu coloco um usuário e a funcionalidade que ele tem direito de acessar(para na hora do login carregar ou não para ele)
Quando crio a primeira funcionalidade funciona perfeitamente e não da erro.

Porém ao criar a segunda(às vezes não da erroe não carrega a permissão também) diretamente no banco(Mysql depois Firebird) ele me permite só que quando vou logar o usuário e dar load das suas pemissões me retorna este erro.

org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000) at org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:126) at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:48) at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:835) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:645) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:314) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy29.isPermitido(Unknown Source) at br.com.tei.controller.login.LogonController.validaUsuario(LogonController.java:205) 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.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:434) at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:372) at br.com.tei.utility.TeiMultiActionController.paramValidations(TeiMultiActionController.java:227) at br.com.tei.utility.TeiMultiActionController.handleRequestInternal(TeiMultiActionController.java:157) at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:857) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:792) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:461) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:426) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:119) at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at com.planetj.servlet.filter.compression.CompressingFilter.handleDoFilter(CompressingFilter.java:210) at com.planetj.servlet.filter.compression.CompressingFilter.doFilter(CompressingFilter.java:200) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:563) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Unknown Source) Caused by: java.sql.BatchUpdateException: Duplicate entry '104' for key 'funcionalidades_id' at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1213) at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:912) at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:294) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246) ... 57 mor

Isso mapeando em permissão OneToOne.

@OneToOne
	@JoinColumn(name="id_funcionalidade")
	private  Funcionalidade funcionalidade;
	
	
	@OneToOne
	@JoinColumn(name="id_usuario")
	private Usuario usuario;

Se tentar qualquer outro relacionamento o sistema não inicializa dando este erro aqui

012-03-27 09:13:04,671 ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:/C:/Cristiano/worspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/TeiGestao/WEB-INF/classes/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: br.com.tei.bean.gestao.Permissao.funcionalidade
Caused by: 
org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: br.com.tei.bean.gestao.Permissao.funcionalidade
	at org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder(CollectionBinder.java:241)
	at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1371)
	at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:733)
	at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:498)
	at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:277)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1286)
	at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
	at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:805)
	at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:745)
	at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:134)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1202)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1172)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:428)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:284)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
	at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:244)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:187)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630)
	at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3391)
	at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
	at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1309)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1601)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1590)
	at java.lang.Thread.run(Unknown Source)

Segue as minhas classes de entidade

Permissao.java

@Entity
@Table(name="permissao")
public class Permissao implements Serializable{
	
	
	@Id 	@GeneratedValue(strategy = GenerationType.AUTO) @Column(name="id")
	private Long id;
	
	@OneToOne 	@JoinColumn(name="id_funcionalidade")
	private  Funcionalidade funcionalidade;
	
	
	@OneToOne  @JoinColumn(name="id_usuario")
	private Usuario usuario;

	private boolean valido;
	
	public Permissao() {}

geteres e seteres...

Menu.java

@Entity
@Table(name="menu")
public class Menu implements Serializable {

	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name="id")
	private Long idMenu;
	
	@OneToOne
	@JoinColumn(name="id_sistema")
	private Sistema sistema;
	

	@OneToMany
	@LazyCollection(LazyCollectionOption.TRUE)
	List<Funcionalidade> funcionalidades;
	
	private Date criacao;
	private boolean valido;
	
	private String nome;
	
	public Menu() {}

geteres e seteres...

Funcionalidade.java

@Entity
@Table(name="funcionalidade")
public class Funcionalidade implements Serializable{
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name="id")
	private Long idFuncionalidade;
	
	@OneToOne
	@JoinColumn(name="id_sistema")
	private Sistema sistema;
	private String nome;
	private String classe;
	private String metodo;
	private String link;
	private boolean valido;
	public Funcionalidade() {}

geteres e seteres...

UsuarioSistema.java

@Entity
@Table(name="Usuario_sistema")
public class UsuarioSistema implements Serializable {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name="id")
	private Long idCargo;
	
	@OneToOne
	@JoinColumn(name="id_usuario")
	private Usuario usuario;

	@OneToOne
	@JoinColumn(name="id_sistema")
	private Sistema sistema;
	private	boolean admin;
	private boolean valido;

geteres e seteres...

Segue o techo do código no momento em que tento logar o usuário e a excessão é disparada quando o mapemaneto ta One-to-One(Desculpem o código está meio confuso )

//aqui teria que pegar all menus dos sitema que o user pode acessar como naun admin
					for (Sistema sistemas: sistemasValidos) {
						List<Menu>  menus =menusPermitidos(sistemas,usuario);


						List<Funcionalidade> novasFuncionalidades = new ArrayList<Funcionalidade>();
						List<Menu> novosMenus = new ArrayList<Menu>();
						Menu menuaux = new Menu();
						
						for (Menu menu1 : menus) {
							menuaux=menu1;
							System.out.println("--"+menu1.getNome());
							//menuaux=menu1;
							List<Funcionalidade> funcionalidades= menu1.getFuncionalidades();
								for (Funcionalidade funcionalidade : funcionalidades) {
									if(permissaoManager.isPermitido(funcionalidade, usuario)){
										setar=true;
										novasFuncionalidades.add(funcionalidade);
										System.out.println("-----"+funcionalidade.getNome());
									}
									
								}
								if(setar){
									menuaux.setFuncionalidades(novasFuncionalidades);
									novosMenus.add(menuaux);
								}
								
								setar= false;
								
						}
						
						modelMenus.put("menu_"+sistemas.getNomesis(), novosMenus); 
					}
					
					req.getSession().setAttribute("menus", modelMenus);

1 Resposta

M

Borges,

na verdade, ele não está deixando você salvar a nova funcionalidade porque está dando um erro de chave duplicada

"java.sql.BatchUpdateException: Duplicate entry ‘104’ for key ‘funcionalidades_id’ at "

Você pode não estar percebendo isso na hora de salvar porque o Hibernate não necessariamente faz o update logo em seguida (isso depende das configurações). Em geral, o Hibernate faz um cache por questões de performance e executa apenas quando a transação termina ou quando é necessário (de acordo com as suas configurações).

No seu caso, quando você faz um login, você lê os dados do banco e, então, o banco precisa estar atualizado. Nessa hora,o Hibernate tenta atualizar o bano com as informações do cache e você obtem o erro.

Então, você precisa revisar a parte que você cadastra a funcionalidade pra ver se não está repetindo o id da funcionalidade anterior.

Espero ter ajudado.

[]s,
Mauro Takeda

Criado 27 de março de 2012
Ultima resposta 27 de mar. de 2012
Respostas 1
Participantes 2