[jboss-jira] [JBoss JIRA] Commented: (HIBERNATE-36) @ManyToMany associations removed after entity listener @PreUpdate call
Henrique Sousa (JIRA)
jira-events at jboss.com
Wed Jul 19 10:42:11 EDT 2006
[ http://jira.jboss.com/jira/browse/HIBERNATE-36?page=comments#action_12339787 ]
Henrique Sousa commented on HIBERNATE-36:
-----------------------------------------
I still do not know why the many-to-many relations are cleared, however I was able to work around the double flush by setting the flush mode to commit in all queries created due to calls from the entity listener:
entityManager.createQuery("...").setFlushMode(FlushModeType.COMMIT).getSingleResult();
> @ManyToMany associations removed after entity listener @PreUpdate call
> ----------------------------------------------------------------------
>
> Key: HIBERNATE-36
> URL: http://jira.jboss.com/jira/browse/HIBERNATE-36
> Project: Hibernate
> Issue Type: Bug
> Environment: JBoss AS 4.0.4 CR2, Windows XP, JDK 1.5_05
> Reporter: Henrique Sousa
> Assigned To: Steve Ebersole
>
> After calling EntityManager.merge() for an entity, its @EntityListeners @PreUpdate methods are invoked. In the @PreUpdate method, locate another entity with @ManyToMany associations. After the @PreUpdate method completes, the @ManyToMany associations are cleaned. Below is some code which can be tested. Call the doSomething() method in the RemoteInterfaceBean to perform the test.
> /*** Bar.java */
> package com.foo;
> import javax.persistence.Entity;
> import javax.persistence.EntityListeners;
> import javax.persistence.Id;
> import javax.persistence.ManyToOne;
> import javax.persistence.Table;
> @Entity
> @Table(name = "TEST_BAR")
> @EntityListeners(MyListener.class)
> public class Bar {
> private Integer id;
> private String description;
> private MyEntity entity;
>
> @Id
> public Integer getId() {
> return id;
> }
> public String getDescription() {
> return description;
> }
> @ManyToOne
> public MyEntity getEntity() {
> return entity;
> }
>
> public void setId(Integer id) {
> this.id = id;
> }
> public void setDescription(String description) {
> this.description = description;
> }
> public void setEntity(MyEntity entity) {
> this.entity = entity;
> }
>
> public boolean equals(Object obj) {
> if (!(obj instanceof Bar))
> return false;
> Integer other = ((Bar)obj).getId();
> return id == null? other == null: id.equals(other);
> }
>
> public int hashCode() {
> return getClass().getName().hashCode() + (id == null? 0: id.hashCode());
> }
> }
> /*** MyEntity.java */
> package com.foo;
> import java.util.Set;
> import javax.persistence.Entity;
> import javax.persistence.FetchType;
> import javax.persistence.Id;
> import javax.persistence.JoinColumn;
> import javax.persistence.JoinTable;
> import javax.persistence.ManyToMany;
> import javax.persistence.Table;
> @Entity
> @Table(name = "TEST_ENTITY")
> public class MyEntity {
>
> private Integer id;
> private String description;
> private Set<Target> targets;
>
> @Id
> public Integer getId() {
> return id;
> }
> public String getDescription() {
> return description;
> }
> @ManyToMany(fetch = FetchType.LAZY)
> @JoinTable(name = "TEST_ASSOCIATION",
> joinColumns = {@JoinColumn(name = "ENTITY")},
> inverseJoinColumns = {@JoinColumn(name = "TARGET")})
> public Set<Target> getTargets() {
> return targets;
> }
> public void setId(Integer id) {
> this.id = id;
> }
> public void setDescription(String description) {
> this.description = description;
> }
> public void setTargets(Set<Target> targets) {
> this.targets = targets;
> }
>
> public boolean equals(Object obj) {
> if (!(obj instanceof MyEntity))
> return false;
> Integer other = ((MyEntity)obj).getId();
> return id == null? other == null: id.equals(other);
> }
>
> public int hashCode() {
> return getClass().getName().hashCode() + (id == null? 0: id.hashCode());
> }
> }
> /*** MyListener.java */
> package com.foo;
> import javax.naming.InitialContext;
> import javax.persistence.PrePersist;
> import javax.persistence.PreUpdate;
> public class MyListener {
> private static ThreadLocal<Object> running = new ThreadLocal<Object>();
>
> @PrePersist
> @PreUpdate
> public void test(Bar bar) {
> System.out.println("Started listener");
> if (running.get() != null) {
> System.out.println("Already running on this thread! Interrupting listener");
> return;
> }
> running.set(new Object());
> try {
> RemoteInterface ejb = (RemoteInterface)new InitialContext().lookup(
> "WorldNet/RemoteInterfaceBean/remote");
> MyEntity entity = ejb.getEntity();
> bar.setEntity(entity);
> System.out.println("entity description: " + entity.getDescription());
> System.out.println("bar id: " + bar.getId());
> System.out.println("Finished listener");
> }
> catch (Exception e) {
> e.printStackTrace();
> }
> finally {
> running.set(null);
> }
> }
>
> }
> /*** RemoteInterface.java */
> package com.foo;
> import javax.ejb.Remote;
> @Remote
> public interface RemoteInterface {
> void doSomething();
>
> MyEntity getEntity();
>
> }
> /*** RemoteInterfaceBean.java */
> package com.foo;
> import java.util.Random;
> import javax.ejb.Stateless;
> import javax.persistence.EntityManager;
> import javax.persistence.PersistenceContext;
> @Stateless
> public class RemoteInterfaceBean implements RemoteInterface {
> static EntityManager staticPersistence;
>
> @PersistenceContext
> private EntityManager persistence;
>
> public void doSomething() {
> simplify();
> Bar bar = new Bar();
> bar.setId(5);
> bar.setDescription("" + new Random().nextInt());
> persistence.merge(bar); // MUST be merge, not persist!!!
> }
>
> public MyEntity getEntity() {
> MyEntity entity = (MyEntity)persistence.createQuery(
> "select x from MyEntity x join fetch x.targets").getSingleResult();
> return entity;
> }
>
> private void simplify() {
> staticPersistence = persistence;
> }
> }
> /*** Target.java */
> package com.foo;
> import javax.persistence.Entity;
> import javax.persistence.Id;
> import javax.persistence.Table;
> @Entity
> @Table(name = "TEST_TARGET")
> public class Target {
>
> private Integer id;
> private String description;
>
> @Id
> public Integer getId() {
> return id;
> }
> public String getDescription() {
> return description;
> }
> public void setId(Integer id) {
> this.id = id;
> }
> public void setDescription(String description) {
> this.description = description;
> }
>
> public boolean equals(Object obj) {
> if (!(obj instanceof Target))
> return false;
> Integer other = ((Target)obj).getId();
> return id == null? other == null: id.equals(other);
> }
>
> public int hashCode() {
> return getClass().getName().hashCode() + (id == null? 0: id.hashCode());
> }
> }
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the jboss-jira
mailing list