1

在以下装修和条件下,

/**
 * passsalt.
 */
@JoinColumn(name = "PASSSALT_ID", nullable = false)
@OneToOne(cascade = {CascadeType.PERSIST,
                     CascadeType.MERGE, // is this actually required?
                     CascadeType.REMOVE},
          optional = false, orphanRemoval = true)
@NotNull
@XmlTransient
private Morton passsalt;
  • passsalt必须与该实体一起存在。( CascadeType.PERSIST)
  • passsalt可以用新detached实例替换。( CascadeType.MERGE?)
  • passsalt删除此实体时必须删除。( CascadeType.REMOVE)
  • Morton没有要更新的字段

问题:CascadeType.MERGE是强制性的吗?

我在有无的情况下进行了测试,没有CascadeType.MERGE它似乎也可以工作。

Q2:问题标题中的“是”是否正确?应该是“是”吗?

这是一种替换的方法passsalt

public boolean nassword(final Shadow reference, final byte[] password,
                        final byte[] nassword) {

    passsalt = new Morton();
    passcode = passsalt.salty(nassword);

    return true;
}

我用以下方法进行了测试。

@Test(enabled = true, invocationCount = 1)
public void testNassword0() {
    final EntityManager manager = LocalPU.createEntityManager();
    try {
        final EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        try {
            final String username = newUsername(manager);
            final byte[] password = newPassword();
            Shadow shadow = persistInstance(manager, username, password);
            Assert.assertTrue(shadow.puthenticate(shadow, password));
            System.out.println("=========================================");
            LOGGER.log(Level.INFO, "mortons: {0}",
                       MORTONS(manager, 0, 1024));
            final byte[] nassword = newPassword();
            shadow.nassword(shadow, password, nassword);
            shadow = manager.merge(shadow);
            manager.flush();
            System.out.println("=========================================");
            LOGGER.log(Level.INFO, "mortons: {0}",
                       MORTONS(manager, 0, 1024));
            Assert.assertFalse(shadow.puthenticate(shadow, password));
            Assert.assertTrue(shadow.puthenticate(shadow, nassword));
            transaction.commit();
        } catch (Exception e) {
            transaction.rollback();
            e.printStackTrace(System.err);
            Assert.fail(e.getMessage());
        }
    } finally {
        manager.close();
    }
}

这是输出。

4월 02, 2013 11:55:03 오전 org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 4.3.0.Final
[EL Info]: 2013-04-02 11:55:03.897--ServerSession(571229670)--EclipseLink, version: Eclipse Persistence Services - 2.3.2.v20111125-r10461
[EL Info]: 2013-04-02 11:55:04.744--ServerSession(571229670)--file:/E:/svnwc/jinahya.googlecode.com/trunk/com.googlecode.jinahya/jinahya-ee/target/test-classes/_localPU login successful
4월 02, 2013 11:55:06 오전 com.googlecode.jinahya.persistence.Morton _PrePersist
INFO: _PrePersist(): Morton@1760972179&id=1048576
4월 02, 2013 11:55:06 오전 com.googlecode.jinahya.persistence.Shadow puthenticate
INFO: puthenticate(Shadow@1311874806?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[B@57d01cc, [B@5200fae4)
4월 02, 2013 11:55:06 오전 com.googlecode.jinahya.persistence.Shadow puthenticate
INFO: passsalt: Morton@1760972179&id=1048576
=========================================
4월 02, 2013 11:55:08 오전 com.googlecode.jinahya.persistence.ShadowTest testNassword0
INFO: mortons: [Morton@1760972179&id=1048576]
4월 02, 2013 11:55:08 오전 com.googlecode.jinahya.persistence.Shadow nassword
INFO: nassword(Shadow@1311874806?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[B@57d01cc, [B@5200fae4, [B@1b6ac76b)
4월 02, 2013 11:55:08 오전 com.googlecode.jinahya.persistence.Shadow puthenticate
INFO: puthenticate(Shadow@1311874806?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[B@57d01cc, [B@5200fae4)
4월 02, 2013 11:55:08 오전 com.googlecode.jinahya.persistence.Shadow puthenticate
INFO: passsalt: Morton@1760972179&id=1048576
4월 02, 2013 11:55:11 오전 com.googlecode.jinahya.persistence.Morton _PrePersist
INFO: _PrePersist(): Morton@93935309&id=1048577
=========================================
4월 02, 2013 11:55:11 오전 com.googlecode.jinahya.persistence.ShadowTest testNassword0
INFO: mortons: [Morton@93935309&id=1048577]
4월 02, 2013 11:55:11 오전 com.googlecode.jinahya.persistence.Shadow puthenticate
INFO: puthenticate(Shadow@1311874806?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[B@641e8314, [B@5200fae4)
4월 02, 2013 11:55:11 오전 com.googlecode.jinahya.persistence.Shadow puthenticate
INFO: passsalt: Morton@93935309&id=1048577
4월 02, 2013 11:55:12 오전 com.googlecode.jinahya.persistence.Shadow puthenticate
INFO: puthenticate(Shadow@1311874806?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[B@641e8314, [B@1b6ac76b)
4월 02, 2013 11:55:12 오전 com.googlecode.jinahya.persistence.Shadow puthenticate
INFO: passsalt: Morton@93935309&id=1048577

总之,

After persisted ->           mortons: [Morton@1760972179&id=1048576]
After replaced and merged -> mortons: [Morton@93935309&id=1048577]
4

1 回答 1

3

简短的回答,它不是必需的。

级联持久化和合并是分开的事情。当您在拥有实体上调用 persist 时使用 Cascade Persist,从而导致在引用的 passsalt 上也调用 persist。如果 cascade persist 在关系上,则暗示在调用刷新或提交时也会找到引用新对象。

另一方面,合并以相同的方式应用于合并操作。当您在实体上调用合并时,它会导致在 passsalt 上也调用合并。如果它存在并且刚刚分离,则将获取更改。如果它是新的,它将被插入,类似于调用persist。当未指定级联合并并且关系引用分离的对象时会发生什么被规范涵盖,但如果实体是新实体会发生什么似乎是灰色的。它声明返回的拥有实体引用了 passsalt 的托管实例,这意味着它无论如何都会被插入,因为托管实例需要在刷新或提交时与数据库同步。所以它应该没有效果,但是根据您使用合并 api 的方式以及您的 JPA 提供程序的行为方式,您可能希望保持它的设置。

此外,您正在使用 orphanRemoval,因此级联删除是隐含的并且不需要。OrphanRemoval 意味着引用的 passsalt 不能在没有所有者实体的情况下存在,因此当所有者被删除或取消引用 passsalt 时,它将从数据库中删除而无需级联删除设置。

于 2013-04-02T14:24:20.340 回答