Skip to content

Commit

Permalink
Issue #2343 - EclipseLink disallows @Version attribute of type java.…
Browse files Browse the repository at this point in the history
…time.LocalDateTime - code refactoring plus additional unit test

Signed-off-by: Radek Felcman <[email protected]>
  • Loading branch information
rfelcman committed Feb 4, 2025
1 parent 0acb197 commit 860e057
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 44 deletions.
18 changes: 17 additions & 1 deletion jpa/eclipselink.jpa.testapps/jpa.test.persistence32/pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2023, 2025 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -66,8 +66,24 @@
<id>default-test</id>
<configuration>
<argLine>-javaagent:${org.eclipse.persistence:org.eclipse.persistence.jpa:jar} @{argLine}</argLine>
<excludes>
<exclude>org.eclipse.persistence.testing.tests.jpa.persistence32.VersionUnsupportedTestSuite</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>unsupported-version-type-test</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<!--Must be in separated execution due a EclipseLink JPA agent-->
<include>org.eclipse.persistence.testing.tests.jpa.persistence32.VersionUnsupportedTestSuite</include>
</includes>
</configuration>
</execution>

</executions>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
// Bug #2343 test to verify LocalDateTime as @Version attribute
@Entity
@Table(name="PERSISTENCE32_LDT_VERSION_ENTITY")
public class LdtVersionEntity {
public class LocalDateTimeVersionEntity {

@Id
private int id;
Expand All @@ -32,13 +32,13 @@ public class LdtVersionEntity {

private String name;

public LdtVersionEntity(int id, LocalDateTime lastUpdated, String name) {
public LocalDateTimeVersionEntity(int id, LocalDateTime lastUpdated, String name) {
this.id = id;
this.lastUpdated = lastUpdated;
this.name = name;
}

public LdtVersionEntity() {
public LocalDateTimeVersionEntity() {
this(-1, null, null);
}

Expand Down Expand Up @@ -71,9 +71,9 @@ public boolean equals(Object obj) {
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
return id == ((LdtVersionEntity) obj).id
&& Objects.equals(name, ((LdtVersionEntity) obj).name)
&& Objects.equals(lastUpdated, ((LdtVersionEntity) obj).lastUpdated);
return id == ((LocalDateTimeVersionEntity) obj).id
&& Objects.equals(name, ((LocalDateTimeVersionEntity) obj).name)
&& Objects.equals(lastUpdated, ((LocalDateTimeVersionEntity) obj).lastUpdated);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.persistence.testing.models.jpa.persistence32;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Version;

import java.sql.Timestamp;
import java.util.Objects;

// Bug #2343
@Entity
@Table(name="PERSISTENCE32_UNSUPPORTED_VERSION_ENTITY")
public class UnsupportedVersionTypeEntity {

@Id
private int id;

private Timestamp lastUpdated;

@Version
private String name;

public UnsupportedVersionTypeEntity(int id, Timestamp lastUpdated, String name) {
this.id = id;
this.lastUpdated = lastUpdated;
this.name = name;
}

public UnsupportedVersionTypeEntity() {
this(-1, null, null);
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Timestamp getLastUpdated() {
return lastUpdated;
}

public void setLastUpdated(Timestamp lastUpdated) {
this.lastUpdated = lastUpdated;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
return id == ((UnsupportedVersionTypeEntity) obj).id
&& Objects.equals(name, ((UnsupportedVersionTypeEntity) obj).name)
&& Objects.equals(lastUpdated, ((UnsupportedVersionTypeEntity) obj).lastUpdated);
}

@Override
public int hashCode() {
return Objects.hash(id, name, lastUpdated);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("InstantVersionEntity {id=");
sb.append(id);
sb.append(", name=");
sb.append(name);
sb.append(", lastUpdated=");
sb.append(lastUpdated);
sb.append("}");
return sb.toString();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!--
Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0 which is available at
http://www.eclipse.org/legal/epl-2.0,
or the Eclipse Distribution License v. 1.0 which is available at
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
-->

<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
version="3.0">

<persistence-unit name="persistence32_unsupported_version_type" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>org.eclipse.persistence.testing.models.jpa.persistence32.UnsupportedVersionTypeEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="jakarta.persistence.schema-generation.database.action" value="none"/>
<property name="eclipselink.logging.level" value="${eclipselink.logging.level}"/>
<property name="eclipselink.logging.level.sql" value="${eclipselink.logging.sql.level}"/>
<property name="eclipselink.logging.parameters" value="${eclipselink.logging.parameters}"/>
</properties>
</persistence-unit>

</persistence>
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>org.eclipse.persistence.testing.models.jpa.persistence32.VersionEntity</class>
<class>org.eclipse.persistence.testing.models.jpa.persistence32.InstantVersionEntity</class>
<class>org.eclipse.persistence.testing.models.jpa.persistence32.LdtVersionEntity</class>
<class>org.eclipse.persistence.testing.models.jpa.persistence32.LocalDateTimeVersionEntity</class>
<class>org.eclipse.persistence.testing.models.jpa.persistence32.TimestampVersionEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@

import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.testing.models.jpa.persistence32.InstantVersionEntity;
import org.eclipse.persistence.testing.models.jpa.persistence32.LdtVersionEntity;
import org.eclipse.persistence.testing.models.jpa.persistence32.LocalDateTimeVersionEntity;
import org.eclipse.persistence.testing.models.jpa.persistence32.TimestampVersionEntity;

public abstract class AbstractVersionSuite extends AbstractSuite {

// LdtVersionEntity instances
static final LdtVersionEntity[] LDT_ENTITIES = new LdtVersionEntity[] {
static final LocalDateTimeVersionEntity[] LDT_ENTITIES = new LocalDateTimeVersionEntity[] {
null, // Skip array index 0
new LdtVersionEntity(1, LocalDateTime.now(), "First"),
new LdtVersionEntity(2, LocalDateTime.now(), "Second"),
new LdtVersionEntity(3, LocalDateTime.now(), "Third")
new LocalDateTimeVersionEntity(1, LocalDateTime.now(), "First"),
new LocalDateTimeVersionEntity(2, LocalDateTime.now(), "Second"),
new LocalDateTimeVersionEntity(3, LocalDateTime.now(), "Third")
};

// InstantVersionEntity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import jakarta.persistence.OptimisticLockException;
import junit.framework.Test;
import org.eclipse.persistence.testing.models.jpa.persistence32.InstantVersionEntity;
import org.eclipse.persistence.testing.models.jpa.persistence32.LdtVersionEntity;
import org.eclipse.persistence.testing.models.jpa.persistence32.LocalDateTimeVersionEntity;
import org.eclipse.persistence.testing.models.jpa.persistence32.TimestampVersionEntity;

/**
Expand All @@ -27,8 +27,8 @@
public class VersionTest extends AbstractVersionSuite {

// LdtVersionEntity instances
private static final LdtVersionEntity[] LDT_ENTITIES_INSERT = new LdtVersionEntity[] {
new LdtVersionEntity(4, LocalDateTime.now(), "Fourth"),
private static final LocalDateTimeVersionEntity[] LDT_ENTITIES_INSERT = new LocalDateTimeVersionEntity[] {
new LocalDateTimeVersionEntity(4, LocalDateTime.now(), "Fourth"),
};

// LdtVersionEntity instances
Expand Down Expand Up @@ -68,42 +68,42 @@ public VersionTest(String name) {
}

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

public void testPersistLdtVersionEntity() {
emf.runInTransaction(em -> em.persist(LDT_ENTITIES_INSERT[0]));
LdtVersionEntity entity = emf.callInTransaction(em -> em
.createQuery("SELECT e FROM LdtVersionEntity e WHERE e.id=:id",
LdtVersionEntity.class)
LocalDateTimeVersionEntity entity = emf.callInTransaction(em -> em
.createQuery("SELECT e FROM LocalDateTimeVersionEntity e WHERE e.id=:id",
LocalDateTimeVersionEntity.class)
.setParameter("id", 4)
.getSingleResult());
assertEquals(LDT_ENTITIES_INSERT[0], entity);
}

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

public void testUpdateCollisionLdtVersionEntity() {
LdtVersionEntity entity1 = emf.callInTransaction(em -> em.find(LdtVersionEntity.class, LDT_ENTITIES[3].getId()));
LdtVersionEntity entity2 = emf.callInTransaction(em -> em.find(LdtVersionEntity.class, LDT_ENTITIES[3].getId()));
LocalDateTimeVersionEntity entity1 = emf.callInTransaction(em -> em.find(LocalDateTimeVersionEntity.class, LDT_ENTITIES[3].getId()));
LocalDateTimeVersionEntity entity2 = emf.callInTransaction(em -> em.find(LocalDateTimeVersionEntity.class, LDT_ENTITIES[3].getId()));
// 1st attempt to persist entity1 shall pass, it will make entity2 invalid (old version)
emf.runInTransaction(em -> {
LdtVersionEntity e = em.merge(entity1);
LocalDateTimeVersionEntity e = em.merge(entity1);
e.setName(entity1.getName() + "1st");
});
// 2nd attempt to persist entity2 shall fail
try {
emf.runInTransaction(em -> {
LdtVersionEntity e = em.merge(entity2);
LocalDateTimeVersionEntity e = em.merge(entity2);
e.setName(entity1.getName() + "1st");
});
fail("Attempt to persist instance with old version shall fail.");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.persistence.testing.tests.jpa.persistence32;

import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.testing.framework.jpa.junit.JUnitTestCase;

import java.util.Properties;

/**
* Verify jakarta.persistence 3.2 @Version attribute types (unsupported type to get exception)
*/
public class VersionUnsupportedTestSuite extends JUnitTestCase {

public VersionUnsupportedTestSuite(String name) {
super(name);
}

public static Test suite() {
TestSuite suite = new TestSuite("VersionUnsupportedTestSuite");
suite.addTest(new VersionUnsupportedTestSuite("testPersistUnsupportedVersionTypeEntity"));
return suite;
}


@Override
public String getPersistenceUnitName() {
return "persistence32_unsupported_version_type";
}

public void testPersistUnsupportedVersionTypeEntity() {
//Special persistence.xml file is needed due a EclipseLink JPA agent
Properties properties = new Properties();
properties.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/persistence-unsupported-version-type.xml");
try (EntityManagerFactory emf = Persistence.createEntityManagerFactory(getPersistenceUnitName(), properties)){
fail("Attempt to continue with unsupported version type shall fail during EntityManagerFactory creation.");
} catch (Exception ex) {
Throwable cause = ex;
while(cause.getCause() != null && cause.getCause() != cause) {
cause = cause.getCause();
if (cause instanceof ValidationException) {
assertTrue(cause.getMessage().contains("is not valid for a version property"));
return;
}
}
fail("Attempt to continue with unsupported version type shall fail as ValidationException was not detected.");
}
}
}
Loading

0 comments on commit 860e057

Please sign in to comment.