From e1ec0bcdfe366b2a51efbfd57292ffda73133de0 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 25 Apr 2014 22:34:03 +1200 Subject: [PATCH] Test and Fix for #39 - TestOnCascadeDeleteChildrenWithCompositeKeys from hei1233212000, with fix included --- ...ascadeDeleteChildrenWithCompositeKeys.java | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 src/test/java/com/avaje/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java diff --git a/src/test/java/com/avaje/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java b/src/test/java/com/avaje/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java new file mode 100644 index 000000000..a989eb717 --- /dev/null +++ b/src/test/java/com/avaje/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java @@ -0,0 +1,214 @@ +package com.avaje.tests.compositekeys; + +import static org.junit.Assert.assertEquals; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Embeddable; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.junit.Before; +import org.junit.Test; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; +import com.avaje.ebeaninternal.api.SpiEbeanServer; +import com.avaje.ebeaninternal.server.deploy.BeanDescriptor; +import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany; + +/** + * @see https://groups.google.com/forum/#!topic/ebean/VD1MV2-LrOc + */ +public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase { + @Before public void before() { + // remove all the User records first + Ebean.delete(Ebean.find(User.class).findList()); + + // insert 2 User records + Ebean.insert(new User(1L)); + Ebean.insert(new User(2L)); + } + + /** + * work fine when delete User one by one + */ + @Test public void testDeleteById() { + assertEquals(2, Ebean.find(User.class).findList().size()); + Ebean.delete(User.class, 1L); + Ebean.delete(User.class, 2L); + assertEquals(0, Ebean.find(User.class).findList().size()); + } + + /** + * Wrong SQL is generated when deleting user by list of ID + * SQL generated: delete from user_role where (user_id) in ((?,?),(?,?)) + */ + @Test public void testDeleteByIdList() { + assertEquals(2, Ebean.find(User.class).findList().size()); + List ids = new ArrayList(); + ids.add(1L); + ids.add(2L); + + Ebean.delete(User.class, ids); // PersistenceException would be thrown here + assertEquals(0, Ebean.find(User.class).findList().size()); + } + + @Test public void testFindByParentIdList() { + assertEquals(2, Ebean.find(User.class).findList().size()); + + SpiEbeanServer spiServer = (SpiEbeanServer)Ebean.getServer(null); + + BeanDescriptor beanDescriptor = + spiServer.getBeanDescriptor(TestOnCascadeDeleteChildrenWithCompositeKeys.User.class); + + BeanPropertyAssocMany beanProperty = (BeanPropertyAssocMany)beanDescriptor.getBeanProperty("userRoles"); + + List ids = new ArrayList(); + ids.add(1L); + ids.add(2L); + + beanProperty.findIdsByParentId(null, ids, null, null); + } + + @Entity @Table(name = "em_user") public static class User { + private Long id; + private String name; + private Set userRoles; + + public User() {} + + public User(Long id) { + this.id = id; + } + + @Id public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @OneToMany(cascade = CascadeType.REMOVE) public Set getUserRoles() { + return userRoles; + } + + public void setUserRoles(Set userRoles) { + this.userRoles = userRoles; + } + } + + @Entity @Table(name = "em_user_role") public static class UserRole implements Serializable { + private static final long serialVersionUID = 1L; + private UserRolePK pk; + private User user; + private Role role; + + @EmbeddedId public UserRolePK getPk() { + return pk; + } + + public void setPk(UserRolePK pk) { + this.pk = pk; + } + + @ManyToOne @JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false) public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + @ManyToOne @JoinColumn(name = "role_id", nullable = false, insertable = false, updatable = false) public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + @Embeddable public static class UserRolePK implements Serializable { + private static final long serialVersionUID = 1L; + private Long userId; + private Long roleId; + + @Override public int hashCode() { + return userId == null || roleId == null ? 0 : (int) (userId + roleId); + } + + @Override public boolean equals(Object other) { + if (userId == null || roleId == null) return false; + if (other instanceof UserRolePK) { + UserRolePK otherPk = (UserRolePK) other; + return userId.equals(otherPk.userId) && roleId.equals(otherPk.roleId); + } + return false; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getRoleId() { + return roleId; + } + + public void setRoleId(Long roleId) { + this.roleId = roleId; + } + } + } + + @Entity @Table(name = "em_role") public static class Role { + private Long id; + private String name; + private Set userRoles; + + @Id public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @OneToMany(cascade = CascadeType.REMOVE) public Set getUserRoles() { + return userRoles; + } + + public void setUserRoles(Set userRoles) { + this.userRoles = userRoles; + } + } +} \ No newline at end of file