Ответ 1
Я использую orphanRemoval=true
с однонаправленной ассоциацией "один-ко-многим" без каких-либо проблем.
И на самом деле, я проверил ваш код и следующий сценарий (AbstractPolicyRule
правильно реализовать equals
/hashCode
):
Category category = new Category();
AbstractPolicyRule policyRule1 = new AbstractPolicyRule("foo");
category.addToActivePolicyRules(policyRule1);
em.persist(category);
em.flush();
assertNotNull(category.getId());
assertNotNull(category.getActivePolicyRules());
assertEquals(1, category.getActivePolicyRules().size());
category.removeFromActivePolicyRules(policyRule1);
category.addToActivePolicyRules(new AbstractPolicyRule("bar"));
// category = em.merge(category); // works with or without
em.flush();
assertEquals(1, category.getActivePolicyRules().size());
работает как ожидалось. Ниже созданных трасс:
22:54:30.817 [main] DEBUG org.hibernate.SQL - insert into Category (id, category_name) values (null, ?) Hibernate: insert into Category (id, category_name) values (null, ?) 22:54:30.824 [main] TRACE org.hibernate.type.StringType - binding null to parameter: 1 22:54:30.844 [main] DEBUG o.h.id.IdentifierGeneratorHelper - Natively generated identity: 1 ... 22:54:30.872 [main] DEBUG org.hibernate.SQL - insert into AbstractPolicyRule (id, name) values (null, ?) Hibernate: insert into AbstractPolicyRule (id, name) values (null, ?) 22:54:30.873 [main] TRACE org.hibernate.type.StringType - binding 'foo' to parameter: 1 22:54:30.874 [main] DEBUG o.h.id.IdentifierGeneratorHelper - Natively generated identity: 1 ... 22:54:30.924 [main] DEBUG org.hibernate.SQL - update AbstractPolicyRule set category_policy_id=? where id=? Hibernate: update AbstractPolicyRule set category_policy_id=? where id=? 22:54:30.927 [main] TRACE org.hibernate.type.LongType - binding '1' to parameter: 1 22:54:30.928 [main] TRACE org.hibernate.type.LongType - binding '1' to parameter: 2 22:54:30.929 [main] DEBUG o.h.p.c.AbstractCollectionPersister - done inserting collection: 1 rows inserted 22:54:30.929 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - Executing batch size: 1 ... 22:54:30.945 [main] DEBUG org.hibernate.SQL - insert into AbstractPolicyRule (id, name) values (null, ?) Hibernate: insert into AbstractPolicyRule (id, name) values (null, ?) 22:54:30.948 [main] TRACE org.hibernate.type.StringType - binding 'bar' to parameter: 1 22:54:30.948 [main] DEBUG o.h.id.IdentifierGeneratorHelper - Natively generated identity: 2 ... 22:54:30.990 [main] DEBUG org.hibernate.SQL - update AbstractPolicyRule set category_policy_id=null where category_policy_id=? and id=? Hibernate: update AbstractPolicyRule set category_policy_id=null where category_policy_id=? and id=? 22:54:30.991 [main] TRACE org.hibernate.type.LongType - binding '1' to parameter: 1 22:54:30.992 [main] TRACE org.hibernate.type.LongType - binding '1' to parameter: 2 22:54:30.993 [main] DEBUG o.h.p.c.AbstractCollectionPersister - done deleting collection rows: 1 deleted 22:54:30.993 [main] DEBUG o.h.p.c.AbstractCollectionPersister - Inserting rows of collection: [com.stackoverflow.q3304092.Category.activePolicyRules#1] 22:54:30.994 [main] DEBUG org.hibernate.jdbc.AbstractBatcher - Executing batch size: 1 ... 22:54:30.996 [main] DEBUG org.hibernate.SQL - update AbstractPolicyRule set category_policy_id=? where id=? Hibernate: update AbstractPolicyRule set category_policy_id=? where id=? 22:54:30.997 [main] TRACE org.hibernate.type.LongType - binding '1' to parameter: 1 22:54:30.998 [main] TRACE org.hibernate.type.LongType - binding '2' to parameter: 2 22:54:31.002 [main] DEBUG o.h.p.c.AbstractCollectionPersister - done inserting rows: 1 inserted ... 22:54:31.015 [main] DEBUG org.hibernate.SQL - delete from AbstractPolicyRule where id=? Hibernate: delete from AbstractPolicyRule where id=? 22:54:31.017 [main] TRACE org.hibernate.type.LongType - binding '1' to parameter: 1
Первое правило политики удаляется.
Если это не отражает то, что вы делаете, вы должны, возможно, предоставить больше кода.
Обновление: Отвечая на комментарий от OP...
Ничего себе, я просто сменил вызов saveOrUpdate для слияния, и теперь он удаляется соответствующим образом. У вас есть понимание, почему это?
Просто предположим: поскольку orphanRemoval
- вещь JPA, интересно, будет ли saveOrUpdate
работать с ней соответствующим образом (на самом деле, я думал, что вы использовали API EntityManager
, так как вы упомянули JPA).