(Resolvido) Vraptor + Ajax + Open session

4 respostas
marcio89

Pessoal, bom dia.
Estou com um problema que tá me tirando do sério e espero que vocês possam me ajudar. Não sei se tem muito a ver com o Vraptor, mas como eu estou utilizando dele, acredito que a solução possa estar no framework.

Seguinte, tenho a seguinte classe para armazenar meu usuário na sessão.

@Component
@SessionScoped
public class UserSession {
	private User user;
}

Classe avaliação:

*/
@Entity
@Table
public class Rating {

	@Id
	@Column
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;

	@JoinColumn
	@OneToOne(cascade = CascadeType.ALL)
	private User user;


}

Classe usuário:

@Entity
@Table
public class User{
        @Column
	@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	private Collection<Rating> ratings;
}

Quando eu tento salvar uma avalição, usando AJAX eu faço assim:

public void newRating(final Rating rating) throws InterruptedException {
		rating.setDate(new GregorianCalendar());
		rating.setUser(this.userSession.getUser());
		this.dao.saveOrUpdate(rating);
	}

E ai o resultaodo:

Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [br.com.realsale.entity.User#marcio.viegas89]
at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:638)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:305)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:450)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:282)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673)
at br.com.realsale.dao.DAO.saveOrUpdate(DAO.java:153)
at br.com.realsale.service.RatingService.newRating(RatingService.java:21)
at br.com.realsale.controller.RatingController.newRating(RatingController.java:31)
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 br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61)
... 47 more

Qual seria a forma correta de fazer isso esse save ? Sabendo que eu posso chamar essa função 5 vezes seguidas da view.
Valeu.

4 Respostas

Rafael_Guerreiro

Você precisa usar o mesmo objeto que o Hibernate está usando. Para isso, você precisa fazer um get(User.class, user.getId()).

marcio89

Seria legal se eu injetasse o userDAO no userssion para no getUser eu retornar esse método que vc disse ?

marcio89

Desculpa, pela falta de educação. Tava empolgado que alguem respondeu.
Muito obrigado pela resposta. Agora aproveitando …

Qual seria a melhor solução, o que vocês fariam para sempre recuperar o usuário. Eu terei que injetar o userDAO em todos as minhas classes Logic ?

Rafael_Guerreiro

Não… Vc não vai conseguir injetar um @RequestScoped em um @SessionScoped… Vc vai ter que receber um userSession em UserDAO e criar um método getActualUser (ou algo assim)…

Relaxa que não teve nenhuma falta de educação…

Criado 31 de dezembro de 2012
Ultima resposta 31 de dez. de 2012
Respostas 4
Participantes 2