Skip to content

Commit 332e8e1

Browse files
authored
Issue #2343 - EclipseLink disallows @Version attribute of type java.time.LocalDateTime - code refactoring plus additional unit test (#2359)
Signed-off-by: Radek Felcman <[email protected]>
1 parent 0acb197 commit 332e8e1

File tree

9 files changed

+250
-43
lines changed

9 files changed

+250
-43
lines changed

jpa/eclipselink.jpa.testapps/jpa.test.persistence32/pom.xml

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
4-
Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
4+
Copyright (c) 2023, 2025 Oracle and/or its affiliates. All rights reserved.
55
66
This program and the accompanying materials are made available under the
77
terms of the Eclipse Public License v. 2.0 which is available at
@@ -66,8 +66,24 @@
6666
<id>default-test</id>
6767
<configuration>
6868
<argLine>-javaagent:${org.eclipse.persistence:org.eclipse.persistence.jpa:jar} @{argLine}</argLine>
69+
<excludes>
70+
<exclude>org.eclipse.persistence.testing.tests.jpa.persistence32.VersionUnsupportedTestSuite</exclude>
71+
</excludes>
6972
</configuration>
7073
</execution>
74+
<execution>
75+
<id>unsupported-version-type-test</id>
76+
<goals>
77+
<goal>test</goal>
78+
</goals>
79+
<configuration>
80+
<includes>
81+
<!--Must be in separated execution due a EclipseLink JPA agent-->
82+
<include>org.eclipse.persistence.testing.tests.jpa.persistence32.VersionUnsupportedTestSuite</include>
83+
</includes>
84+
</configuration>
85+
</execution>
86+
7187
</executions>
7288
</plugin>
7389
<plugin>
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// Bug #2343 test to verify LocalDateTime as @Version attribute
2323
@Entity
2424
@Table(name="PERSISTENCE32_LDT_VERSION_ENTITY")
25-
public class LdtVersionEntity {
25+
public class LocalDateTimeVersionEntity {
2626

2727
@Id
2828
private int id;
@@ -32,13 +32,13 @@ public class LdtVersionEntity {
3232

3333
private String name;
3434

35-
public LdtVersionEntity(int id, LocalDateTime lastUpdated, String name) {
35+
public LocalDateTimeVersionEntity(int id, LocalDateTime lastUpdated, String name) {
3636
this.id = id;
3737
this.lastUpdated = lastUpdated;
3838
this.name = name;
3939
}
4040

41-
public LdtVersionEntity() {
41+
public LocalDateTimeVersionEntity() {
4242
this(-1, null, null);
4343
}
4444

@@ -71,9 +71,9 @@ public boolean equals(Object obj) {
7171
if (obj == null || obj.getClass() != this.getClass()) {
7272
return false;
7373
}
74-
return id == ((LdtVersionEntity) obj).id
75-
&& Objects.equals(name, ((LdtVersionEntity) obj).name)
76-
&& Objects.equals(lastUpdated, ((LdtVersionEntity) obj).lastUpdated);
74+
return id == ((LocalDateTimeVersionEntity) obj).id
75+
&& Objects.equals(name, ((LocalDateTimeVersionEntity) obj).name)
76+
&& Objects.equals(lastUpdated, ((LocalDateTimeVersionEntity) obj).lastUpdated);
7777
}
7878

7979
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0,
7+
* or the Eclipse Distribution License v. 1.0 which is available at
8+
* http://www.eclipse.org/org/documents/edl-v10.php.
9+
*
10+
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11+
*/
12+
package org.eclipse.persistence.testing.models.jpa.persistence32;
13+
14+
import jakarta.persistence.Entity;
15+
import jakarta.persistence.Id;
16+
import jakarta.persistence.Table;
17+
import jakarta.persistence.Version;
18+
19+
import java.sql.Timestamp;
20+
import java.util.Objects;
21+
22+
// Bug #2343
23+
@Entity
24+
@Table(name="PERSISTENCE32_UNSUPPORTED_VERSION_ENTITY")
25+
public class UnsupportedVersionTypeEntity {
26+
27+
@Id
28+
private int id;
29+
30+
private Timestamp lastUpdated;
31+
32+
@Version
33+
private String name;
34+
35+
public UnsupportedVersionTypeEntity(int id, Timestamp lastUpdated, String name) {
36+
this.id = id;
37+
this.lastUpdated = lastUpdated;
38+
this.name = name;
39+
}
40+
41+
public UnsupportedVersionTypeEntity() {
42+
this(-1, null, null);
43+
}
44+
45+
public int getId() {
46+
return id;
47+
}
48+
49+
public void setId(int id) {
50+
this.id = id;
51+
}
52+
53+
public Timestamp getLastUpdated() {
54+
return lastUpdated;
55+
}
56+
57+
public void setLastUpdated(Timestamp lastUpdated) {
58+
this.lastUpdated = lastUpdated;
59+
}
60+
61+
public String getName() {
62+
return name;
63+
}
64+
65+
public void setName(String name) {
66+
this.name = name;
67+
}
68+
69+
@Override
70+
public boolean equals(Object obj) {
71+
if (obj == null || obj.getClass() != this.getClass()) {
72+
return false;
73+
}
74+
return id == ((UnsupportedVersionTypeEntity) obj).id
75+
&& Objects.equals(name, ((UnsupportedVersionTypeEntity) obj).name)
76+
&& Objects.equals(lastUpdated, ((UnsupportedVersionTypeEntity) obj).lastUpdated);
77+
}
78+
79+
@Override
80+
public int hashCode() {
81+
return Objects.hash(id, name, lastUpdated);
82+
}
83+
84+
@Override
85+
public String toString() {
86+
StringBuilder sb = new StringBuilder();
87+
sb.append("InstantVersionEntity {id=");
88+
sb.append(id);
89+
sb.append(", name=");
90+
sb.append(name);
91+
sb.append(", lastUpdated=");
92+
sb.append(lastUpdated);
93+
sb.append("}");
94+
return sb.toString();
95+
}
96+
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!--
2+
3+
Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
4+
5+
This program and the accompanying materials are made available under the
6+
terms of the Eclipse Public License v. 2.0 which is available at
7+
http://www.eclipse.org/legal/epl-2.0,
8+
or the Eclipse Distribution License v. 1.0 which is available at
9+
http://www.eclipse.org/org/documents/edl-v10.php.
10+
11+
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
12+
13+
-->
14+
15+
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
16+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
17+
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
18+
https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
19+
version="3.0">
20+
21+
<persistence-unit name="persistence32_unsupported_version_type" transaction-type="RESOURCE_LOCAL">
22+
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
23+
<class>org.eclipse.persistence.testing.models.jpa.persistence32.UnsupportedVersionTypeEntity</class>
24+
<exclude-unlisted-classes>true</exclude-unlisted-classes>
25+
<properties>
26+
<property name="jakarta.persistence.schema-generation.database.action" value="none"/>
27+
<property name="eclipselink.logging.level" value="${eclipselink.logging.level}"/>
28+
<property name="eclipselink.logging.level.sql" value="${eclipselink.logging.sql.level}"/>
29+
<property name="eclipselink.logging.parameters" value="${eclipselink.logging.parameters}"/>
30+
</properties>
31+
</persistence-unit>
32+
33+
</persistence>

jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/main/resources/META-INF/persistence.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
6161
<class>org.eclipse.persistence.testing.models.jpa.persistence32.VersionEntity</class>
6262
<class>org.eclipse.persistence.testing.models.jpa.persistence32.InstantVersionEntity</class>
63-
<class>org.eclipse.persistence.testing.models.jpa.persistence32.LdtVersionEntity</class>
63+
<class>org.eclipse.persistence.testing.models.jpa.persistence32.LocalDateTimeVersionEntity</class>
6464
<class>org.eclipse.persistence.testing.models.jpa.persistence32.TimestampVersionEntity</class>
6565
<exclude-unlisted-classes>true</exclude-unlisted-classes>
6666
<properties>

jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/AbstractVersionSuite.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@
1717

1818
import org.eclipse.persistence.logging.SessionLog;
1919
import org.eclipse.persistence.testing.models.jpa.persistence32.InstantVersionEntity;
20-
import org.eclipse.persistence.testing.models.jpa.persistence32.LdtVersionEntity;
20+
import org.eclipse.persistence.testing.models.jpa.persistence32.LocalDateTimeVersionEntity;
2121
import org.eclipse.persistence.testing.models.jpa.persistence32.TimestampVersionEntity;
2222

2323
public abstract class AbstractVersionSuite extends AbstractSuite {
2424

2525
// LdtVersionEntity instances
26-
static final LdtVersionEntity[] LDT_ENTITIES = new LdtVersionEntity[] {
26+
static final LocalDateTimeVersionEntity[] LDT_ENTITIES = new LocalDateTimeVersionEntity[] {
2727
null, // Skip array index 0
28-
new LdtVersionEntity(1, LocalDateTime.now(), "First"),
29-
new LdtVersionEntity(2, LocalDateTime.now(), "Second"),
30-
new LdtVersionEntity(3, LocalDateTime.now(), "Third")
28+
new LocalDateTimeVersionEntity(1, LocalDateTime.now(), "First"),
29+
new LocalDateTimeVersionEntity(2, LocalDateTime.now(), "Second"),
30+
new LocalDateTimeVersionEntity(3, LocalDateTime.now(), "Third")
3131
};
3232

3333
// InstantVersionEntity

jpa/eclipselink.jpa.testapps/jpa.test.persistence32/src/test/java/org/eclipse/persistence/testing/tests/jpa/persistence32/VersionTest.java

+13-13
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import jakarta.persistence.OptimisticLockException;
1919
import junit.framework.Test;
2020
import org.eclipse.persistence.testing.models.jpa.persistence32.InstantVersionEntity;
21-
import org.eclipse.persistence.testing.models.jpa.persistence32.LdtVersionEntity;
21+
import org.eclipse.persistence.testing.models.jpa.persistence32.LocalDateTimeVersionEntity;
2222
import org.eclipse.persistence.testing.models.jpa.persistence32.TimestampVersionEntity;
2323

2424
/**
@@ -27,8 +27,8 @@
2727
public class VersionTest extends AbstractVersionSuite {
2828

2929
// LdtVersionEntity instances
30-
private static final LdtVersionEntity[] LDT_ENTITIES_INSERT = new LdtVersionEntity[] {
31-
new LdtVersionEntity(4, LocalDateTime.now(), "Fourth"),
30+
private static final LocalDateTimeVersionEntity[] LDT_ENTITIES_INSERT = new LocalDateTimeVersionEntity[] {
31+
new LocalDateTimeVersionEntity(4, LocalDateTime.now(), "Fourth"),
3232
};
3333

3434
// LdtVersionEntity instances
@@ -68,42 +68,42 @@ public VersionTest(String name) {
6868
}
6969

7070
public void testFindLdtVersionEntity() {
71-
LdtVersionEntity entity = emf.callInTransaction(em -> em.find(LdtVersionEntity.class, 1));
71+
LocalDateTimeVersionEntity entity = emf.callInTransaction(em -> em.find(LocalDateTimeVersionEntity.class, 1));
7272
assertEquals(LDT_ENTITIES[1], entity);
7373
}
7474

7575
public void testPersistLdtVersionEntity() {
7676
emf.runInTransaction(em -> em.persist(LDT_ENTITIES_INSERT[0]));
77-
LdtVersionEntity entity = emf.callInTransaction(em -> em
78-
.createQuery("SELECT e FROM LdtVersionEntity e WHERE e.id=:id",
79-
LdtVersionEntity.class)
77+
LocalDateTimeVersionEntity entity = emf.callInTransaction(em -> em
78+
.createQuery("SELECT e FROM LocalDateTimeVersionEntity e WHERE e.id=:id",
79+
LocalDateTimeVersionEntity.class)
8080
.setParameter("id", 4)
8181
.getSingleResult());
8282
assertEquals(LDT_ENTITIES_INSERT[0], entity);
8383
}
8484

8585
public void testMergeLdtVersionEntity() {
86-
LdtVersionEntity entity = LDT_ENTITIES[2];
86+
LocalDateTimeVersionEntity entity = LDT_ENTITIES[2];
8787
entity.setName(entity.getName() + "Modified");
8888
emf.runInTransaction(em -> em.merge(entity));
89-
LdtVersionEntity dbEntity = emf.callInTransaction(em -> em.find(LdtVersionEntity.class, entity.getId()));
89+
LocalDateTimeVersionEntity dbEntity = emf.callInTransaction(em -> em.find(LocalDateTimeVersionEntity.class, entity.getId()));
9090
// Version will differ so only ID and modified attribute is checked
9191
assertEquals(entity.getId(), dbEntity.getId());
9292
assertEquals(entity.getName(), dbEntity.getName());
9393
}
9494

9595
public void testUpdateCollisionLdtVersionEntity() {
96-
LdtVersionEntity entity1 = emf.callInTransaction(em -> em.find(LdtVersionEntity.class, LDT_ENTITIES[3].getId()));
97-
LdtVersionEntity entity2 = emf.callInTransaction(em -> em.find(LdtVersionEntity.class, LDT_ENTITIES[3].getId()));
96+
LocalDateTimeVersionEntity entity1 = emf.callInTransaction(em -> em.find(LocalDateTimeVersionEntity.class, LDT_ENTITIES[3].getId()));
97+
LocalDateTimeVersionEntity entity2 = emf.callInTransaction(em -> em.find(LocalDateTimeVersionEntity.class, LDT_ENTITIES[3].getId()));
9898
// 1st attempt to persist entity1 shall pass, it will make entity2 invalid (old version)
9999
emf.runInTransaction(em -> {
100-
LdtVersionEntity e = em.merge(entity1);
100+
LocalDateTimeVersionEntity e = em.merge(entity1);
101101
e.setName(entity1.getName() + "1st");
102102
});
103103
// 2nd attempt to persist entity2 shall fail
104104
try {
105105
emf.runInTransaction(em -> {
106-
LdtVersionEntity e = em.merge(entity2);
106+
LocalDateTimeVersionEntity e = em.merge(entity2);
107107
e.setName(entity1.getName() + "1st");
108108
});
109109
fail("Attempt to persist instance with old version shall fail.");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0,
7+
* or the Eclipse Distribution License v. 1.0 which is available at
8+
* http://www.eclipse.org/org/documents/edl-v10.php.
9+
*
10+
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11+
*/
12+
package org.eclipse.persistence.testing.tests.jpa.persistence32;
13+
14+
import jakarta.persistence.EntityManagerFactory;
15+
import jakarta.persistence.Persistence;
16+
import junit.framework.Test;
17+
import junit.framework.TestSuite;
18+
import org.eclipse.persistence.config.PersistenceUnitProperties;
19+
import org.eclipse.persistence.exceptions.ValidationException;
20+
import org.eclipse.persistence.testing.framework.jpa.junit.JUnitTestCase;
21+
22+
import java.util.Properties;
23+
24+
/**
25+
* Verify jakarta.persistence 3.2 @Version attribute types (unsupported type to get exception)
26+
*/
27+
public class VersionUnsupportedTestSuite extends JUnitTestCase {
28+
29+
public VersionUnsupportedTestSuite(String name) {
30+
super(name);
31+
}
32+
33+
public static Test suite() {
34+
TestSuite suite = new TestSuite("VersionUnsupportedTestSuite");
35+
suite.addTest(new VersionUnsupportedTestSuite("testPersistUnsupportedVersionTypeEntity"));
36+
return suite;
37+
}
38+
39+
40+
@Override
41+
public String getPersistenceUnitName() {
42+
return "persistence32_unsupported_version_type";
43+
}
44+
45+
public void testPersistUnsupportedVersionTypeEntity() {
46+
//Special persistence.xml file is needed due a EclipseLink JPA agent
47+
Properties properties = new Properties();
48+
properties.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/persistence-unsupported-version-type.xml");
49+
try (EntityManagerFactory emf = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties)){
50+
fail("Attempt to continue with unsupported version type shall fail during EntityManagerFactory creation.");
51+
} catch (Exception ex) {
52+
Throwable cause = ex;
53+
while(cause.getCause() != null && cause.getCause() != cause) {
54+
cause = cause.getCause();
55+
if (cause instanceof ValidationException) {
56+
assertTrue(cause.getMessage().contains("is not valid for a version property"));
57+
return;
58+
}
59+
}
60+
fail("Attempt to continue with unsupported version type shall fail as ValidationException was not detected.");
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)