Browse Source

Make SpringPersistenceUnitInfo public for custom bootstrapping purposes

See gh-35622
pull/35641/head
Juergen Hoeller 2 months ago
parent
commit
e901516732
  1. 4
      spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java
  2. 7
      spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/MutablePersistenceUnitInfo.java
  3. 67
      spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java

4
spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java

@ -675,7 +675,7 @@ public class DefaultPersistenceUnitManager @@ -675,7 +675,7 @@ public class DefaultPersistenceUnitManager
}
SpringPersistenceUnitInfo pui = this.persistenceUnitInfos.values().iterator().next();
this.persistenceUnitInfos.clear();
return pui.toSmartPersistenceUnitInfo();
return pui.asStandardPersistenceUnitInfo();
}
@Override
@ -691,7 +691,7 @@ public class DefaultPersistenceUnitManager @@ -691,7 +691,7 @@ public class DefaultPersistenceUnitManager
"Persistence unit with name '" + persistenceUnitName + "' already obtained");
}
}
return pui.toSmartPersistenceUnitInfo();
return pui.asStandardPersistenceUnitInfo();
}
}

7
spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/MutablePersistenceUnitInfo.java

@ -34,6 +34,7 @@ import org.springframework.util.Assert; @@ -34,6 +34,7 @@ import org.springframework.util.Assert;
* Spring's mutable equivalent of the JPA
* {@link jakarta.persistence.spi.PersistenceUnitInfo} interface,
* used to bootstrap an {@code EntityManagerFactory} in a container.
* This is the type exposed to {@link PersistenceUnitPostProcessor}.
*
* <p>This implementation is largely a JavaBean, offering mutators
* for all standard {@code PersistenceUnitInfo} properties.
@ -42,10 +43,16 @@ import org.springframework.util.Assert; @@ -42,10 +43,16 @@ import org.springframework.util.Assert;
* (for achieving compatibility between JPA 3.2 and 4.0 and for preventing
* late mutation attempts through {@code PersistenceUnitInfo} downcasts).
*
* <p>For custom bootstrapping purposes, use {@link SpringPersistenceUnitInfo}
* instead, turning it into a {@code jakarta.persistence.spi.PersistenceUnitInfo}
* through {@link SpringPersistenceUnitInfo#asStandardPersistenceUnitInfo()}.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Costin Leau
* @since 2.0
* @see PersistenceUnitPostProcessor#postProcessPersistenceUnitInfo
* @see SpringPersistenceUnitInfo#asStandardPersistenceUnitInfo()
*/
public class MutablePersistenceUnitInfo {

67
spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java

@ -22,6 +22,7 @@ import java.lang.reflect.Proxy; @@ -22,6 +22,7 @@ import java.lang.reflect.Proxy;
import jakarta.persistence.PersistenceUnitTransactionType;
import jakarta.persistence.spi.ClassTransformer;
import jakarta.persistence.spi.PersistenceUnitInfo;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
@ -35,26 +36,56 @@ import org.springframework.util.ReflectionUtils; @@ -35,26 +36,56 @@ import org.springframework.util.ReflectionUtils;
* Subclass of {@link MutablePersistenceUnitInfo} that adds instrumentation hooks based on
* Spring's {@link org.springframework.instrument.classloading.LoadTimeWeaver} abstraction.
*
* <p>This class is restricted to package visibility, in contrast to its superclass.
* <p>As of 7.0, this class is public for custom bootstrapping purposes. A fully configured
* {@code SpringPersistenceUnitInfo} instance can be turned into a standard JPA descriptor
* through {@link #asStandardPersistenceUnitInfo} (returning a JPA 3.2/4.0 adapted proxy).
*
* <p>Note: For post-processing within a {@code LocalContainerEntityManagerFactoryBean}
* bootstrap, the base type {@code MutablePersistenceUnitInfo} is entirely sufficient.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Costin Leau
* @since 2.0
* @see PersistenceUnitManager
* @since 7.0
* @see DefaultPersistenceUnitManager
*/
class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
public class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
private @Nullable LoadTimeWeaver loadTimeWeaver;
private @Nullable ClassLoader classLoader;
/**
* Construct a new SpringPersistenceUnitInfo for custom purposes.
* @param loadTimeWeaver the LoadTimeWeaver to use
*/
public SpringPersistenceUnitInfo(LoadTimeWeaver loadTimeWeaver) {
init(loadTimeWeaver);
}
/**
* Construct a new SpringPersistenceUnitInfo for custom purposes.
* @param classLoader the ClassLoader to use
*/
public SpringPersistenceUnitInfo(ClassLoader classLoader) {
init(classLoader);
}
/**
* Construct a SpringPersistenceUnitInfo for internal purposes.
* @see #init(LoadTimeWeaver)
* @see #init(ClassLoader)
*/
SpringPersistenceUnitInfo() {
}
/**
* Initialize this PersistenceUnitInfo with the LoadTimeWeaver SPI interface
* used by Spring to add instrumentation to the current class loader.
*/
public void init(LoadTimeWeaver loadTimeWeaver) {
void init(LoadTimeWeaver loadTimeWeaver) {
Assert.notNull(loadTimeWeaver, "LoadTimeWeaver must not be null");
this.loadTimeWeaver = loadTimeWeaver;
this.classLoader = loadTimeWeaver.getInstrumentableClassLoader();
@ -64,11 +95,10 @@ class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo { @@ -64,11 +95,10 @@ class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
* Initialize this PersistenceUnitInfo with the current class loader
* (instead of with a LoadTimeWeaver).
*/
public void init(@Nullable ClassLoader classLoader) {
void init(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
}
/**
* This implementation returns the LoadTimeWeaver's instrumentable ClassLoader,
* if specified.
@ -102,20 +132,26 @@ class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo { @@ -102,20 +132,26 @@ class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
return tcl;
}
/**
* Expose a {@link SmartPersistenceUnitInfo} proxy for the persistence unit
* configuration in this {@link MutablePersistenceUnitInfo} instance.
* @since 7.0
* Expose a standard {@code jakarta.persistence.spi.PersistenceUnitInfo} proxy for the
* persistence unit configuration in this {@code SpringPersistenceUnitInfo} instance.
* <p>The returned proxy implements {@code jakarta.persistence.spi.PersistenceUnitInfo}
* (and its extended variant {@link SmartPersistenceUnitInfo}) for use with persistence
* provider bootstrapping. Note that the returned proxy is effectively unmodifiable and
* cannot be downcast to {@code Mutable/SpringPersistenceUnitInfo}.
*/
public SmartPersistenceUnitInfo toSmartPersistenceUnitInfo() {
return (SmartPersistenceUnitInfo) Proxy.newProxyInstance(getClass().getClassLoader(),
public PersistenceUnitInfo asStandardPersistenceUnitInfo() {
return (PersistenceUnitInfo) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class<?>[] {SmartPersistenceUnitInfo.class},
new JpaPersistenceUnitInfoInvocationHandler());
new SmartPersistenceUnitInfoInvocationHandler());
}
private class JpaPersistenceUnitInfoInvocationHandler implements InvocationHandler {
/**
* Invocation handler for a JPA-compliant {@link SmartPersistenceUnitInfo} proxy,
* delegating to the corresponding methods on {@link SpringPersistenceUnitInfo}.
*/
private class SmartPersistenceUnitInfoInvocationHandler implements InvocationHandler {
@SuppressWarnings("unchecked")
@Override
@ -127,7 +163,6 @@ class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo { @@ -127,7 +163,6 @@ class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo {
// Regular methods to be delegated to SpringPersistenceUnitInfo
Method targetMethod = SpringPersistenceUnitInfo.class.getMethod(method.getName(), method.getParameterTypes());
ReflectionUtils.makeAccessible(targetMethod);
Object returnValue = ReflectionUtils.invokeMethod(targetMethod, SpringPersistenceUnitInfo.this, args);
// Special handling for JPA 3.2 vs 4.0 getTransactionType() return type

Loading…
Cancel
Save