0

ソースとターゲットが1.6(maven-compiler-plugin構成)に設定されていますが、埋め込みGlassfish(3.1.2.2)とjunit(4.11)、JDK1.7を使用しています。

以下は私のコードです:

Person.java

@Entity
public class Person implements Serializable {

    private static final long serialVersionUID = 81398385247591972L;

    @Id
    @GeneratedValue
    private Long id;
    @Version
    private Long version;
    @Column(length = 15, nullable = false, unique = true, updatable = false)
    private String username;
    @Column(length = 50)
    private String status;

    // Constructors

    // getters/setters

    // hashCode, equals, toString

}

Service.java

@Stateless
public class Service {

    @PersistenceContext(unitName = "ExamplePU", type = PersistenceContextType.TRANSACTION)
    private EntityManager em;

    public Person add(Person person) {
        em.persist(person);
        return person;
    }

    public Person find(Long id) {
        return em.find(Person.class, id);
    }

    public Person modify(Person person) {
        return em.merge(person);
    }

    // some more code ...

}

ServiceTest.java

public class ServiceTest {

    private static EJBContainer ejbContainer;
    private static Service service;

    // @BeforeClass, @AfterClass, @Before, @After

    @Test
    public void testMerge() {
        Person person;

        /* Step 1 */person = service.add(new Person("username", "status"));
        print("Added : " + person);

        person.setStatus("Away");
        /* Step 2 */person = service.modify(person);
        print("Merged (status change) : " + person);

        person.setUsername("UsErNaMe");
        /* Step 3 */person = service.modify(person);
        print("Merged (username change) : " + person);
    }

    // Some more tests

}

ステップ1は、次のSQLを生成します(予想どおり)。

INSERT INTO PERSON (ID, STATUS, USERNAME, VERSION) VALUES (?, ?, ?, ?)
    bind => [1, status, username, 1]

ステップ2は、次のSQLを生成します(予想どおり)。

UPDATE PERSON SET STATUS = ?, VERSION = ? WHERE ((ID = ?) AND (VERSION = ?))
    bind => [Away, 2, 1, 1]

ステップ3はSQLを生成しませんが、'username'は@Column(...、updatable = false)として注釈が付けられているため、私が期待している例外はスローされません。print(...)メソッドは、次の出力を出力します。

マージ済み(ユーザー名の変更):Person [id = 1、version = 2、username = UsErNaMe、status = Away]

今回、merge()操作はユーザー名を更新しましたが、バージョンは更新していません。また、データベースはEntityManagerキャッシュと同期していません。

これは予想されることですか、それともEclipseLinkのバグですか?

アップデート

期待される結果は、上記のステップ3の例外です。

アップデート

ここにバグを提出しました。

4

1 に答える 1

1

列を更新不可としてマークすると、EclipseLinkは、マージするように指示したユーザーに加えられた唯一の変更がユーザー名であることを検出します。ただし、ユーザー名は更新しないでください。したがって、SQL更新クエリは発行されません。

列を更新不可としてマークした場合、それを更新しないでください。

したがって、物事を明確にするために、観察する動作は予想される動作です。

于 2013-02-27T09:15:21.663 に答える