Skip to content

Commit

Permalink
[master] Bug 539822: Fixes #260 (#261)
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Vissers <[email protected]>
  • Loading branch information
jvissers authored and lukasj committed Dec 19, 2018
1 parent 4926ff0 commit 52dcff1
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.eclipse.persistence.jpa.test.canonical;

public interface BasePersistable {

Long getId();

String getName();

void setName(String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.eclipse.persistence.jpa.test.canonical;

import javax.persistence.Entity;

@Entity
public class DomainClass extends DomainPersistable {

// Holds additional features that one can specify on the DomainInterface
// Essentially this is an enrichment of the persistable

@Override
public Long doSomeBusinessOperation() {

return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.eclipse.persistence.jpa.test.canonical;

public interface DomainInterface extends BasePersistable {

Long doSomeBusinessOperation();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.eclipse.persistence.jpa.test.canonical;

import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;

@StaticMetamodel(DomainPersistable.class)
public class DomainInterface_ {

public static volatile SingularAttribute<DomainPersistable, Long> id;
public static volatile SingularAttribute<DomainPersistable, String> name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.eclipse.persistence.jpa.test.canonical;

import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
public abstract class DomainPersistable implements DomainInterface {

// Holds all standard fields, mapped to something that is going to be persisted in the database

@Id
private Long id;
private String name;

@Override
public Long getId() {

return id;
}

@Override
public String getName() {

return name;
}

@Override
public void setName(String name) {

this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.eclipse.persistence.jpa.test.canonical;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import java.util.Arrays;
import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.PersistenceProvider;
import org.eclipse.persistence.sessions.Session;
import org.junit.Test;

public class TestCanonicalMetaModel {

@Test
public void testUseCanonicalModelFieldName() {

PersistenceProvider persistenceProvider = new PersistenceProvider();
SEPersistenceUnitInfo persistenceUnitInfo = new SEPersistenceUnitInfo();

// For ASM to do its work creating metaclasses
persistenceUnitInfo.setClassLoader(Thread.currentThread().getContextClassLoader());

// We only programmatically add 'leaf' domain classes to pui
persistenceUnitInfo.setManagedClassNames(Arrays.asList(DomainClass.class.getName()));
persistenceUnitInfo.setPersistenceUnitName("canonical-test");
persistenceUnitInfo.setPersistenceUnitRootUrl(DomainClass.class.getProtectionDomain()
.getCodeSource().getLocation());

Properties properties = new Properties();
readProperty(properties, "javax.persistence.jdbc.driver");
readProperty(properties, "javax.persistence.jdbc.url");
readProperty(properties, "javax.persistence.jdbc.user");
readProperty(properties, "javax.persistence.jdbc.password");

// In our actual application we have a generic session customizer that binds a number
// of delegate session customizers in a 'logical' order - for this example however we
// only need to have this 'test' one - see below class
properties.setProperty("eclipselink.session.customizer", CanonicalMetaModelCustomizer.class.getName());

try (AutoCloseableEntityManagerFactory acemf = new AutoCloseableEntityManagerFactory(persistenceProvider,
persistenceUnitInfo, properties)) {
assertThat("The \"name\" field is properly initialized", DomainInterface_.name, notNullValue());
}

}

private void readProperty(Properties properties, String key) {

properties.setProperty(key, System.getProperty(key));
}

/**
* What it is doing is that it will be providing the link between an (impl) 'hidden' persistable and an
* api (exposed) canonical metamodel class.
*/
public static class CanonicalMetaModelCustomizer implements SessionCustomizer {

@Override
public void customize(Session session) throws Exception {

AbstractSession.class.cast(session).addStaticMetamodelClass(
DomainPersistable.class.getName(), DomainInterface_.class.getName());
}
}

/**
* Provides some small cleanup test helper facility.
*/
static class AutoCloseableEntityManagerFactory implements AutoCloseable {

private final EntityManagerFactory entityManagerFactory;
private final EntityManager firstEntityManager;

AutoCloseableEntityManagerFactory(PersistenceProvider persistenceProvider,
SEPersistenceUnitInfo persistenceUnitInfo, Properties properties) {

entityManagerFactory = persistenceProvider.createContainerEntityManagerFactory(persistenceUnitInfo, properties);
firstEntityManager = entityManagerFactory.createEntityManager();
}

@Override
public void close() {

if (firstEntityManager != null) {
firstEntityManager.close();
}

if (entityManagerFactory != null) {
entityManagerFactory.close();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1865,7 +1865,7 @@ public void processStage1() {
*/
public void processStage2() {
// process metamodel mappedSuperclasses separately from entity descriptors
for (MappedSuperclassAccessor msAccessor : getMappedSuperclasses()) {
for (MappedSuperclassAccessor msAccessor : getMetamodelMappedSuperclasses()) {
if (! msAccessor.isProcessed()) {
msAccessor.processMetamodelDescriptor();
}
Expand Down

0 comments on commit 52dcff1

Please sign in to comment.