HHH-14837 - Move to Jakarta EE

improved support for schema tooling settings
This commit is contained in:
Steve Ebersole 2021-09-24 11:01:31 -05:00
parent 3f2d48d7f5
commit 679a919203
10 changed files with 488 additions and 110 deletions

View File

@ -87,43 +87,43 @@ jar {
attributes(
'Main-Class': 'org.hibernate.Version',
// BND Plugin instructions (for OSGi):
'Import-Package': [
'javax.security.auth;resolution:=optional',
// Make javax.security.jacc optional and do not reference a version range (because that's what we used to do)
'javax.security.jacc;resolution:=optional;version=!',
// Make javax.validation optional and do not reference a version range (because that's what we used to do)
'javax.validation;resolution:=optional;version=!',
'javax.validation.constraints;resolution:=optional;version=!',
'javax.validation.groups;resolution:=optional;version=!',
'javax.validation.metadata;resolution:=optional;version=!',
// Make javax.enterprise optional and do not reference a version range (because that's what we used to do)
'!javax.enterprise*',
'javax.enterprise.context.spi;resolution:=optional;version=!',
'javax.enterprise.inject.spi;resolution:=optional;version=!',
// For JPA, we don't want to target the automatically generated range, but a specific version
"javax.persistence;version=\"${project.jpaVersion.osgiName}\"",
// optionals
'jakarta.persistence.spi;resolution:=optional',
'javax.management;resolution:=optional',
'javax.naming.event;resolution:=optional',
'javax.naming.spi;resolution:=optional',
'org.apache.tools.ant;resolution:=optional',
'org.apache.tools.ant.taskdefs;resolution:=optional',
'org.apache.tools.ant.types;resolution:=optional',
'javax.inject;resolution:=optional',
'net.bytebuddy.*;resolution:=optional',
'org.objectweb.jonas_tm;resolution:=optional',
'com.ibm.websphere.jtaextensions;resolution:=optional',
// We must specify the version explicitly to allow Karaf
// to use an older version of JAXB (the only one we can use in Karaf)
"javax.xml.bind.*;version=\"${project.jaxbApiVersionOsgiRange}\"",
// Temporarily support JTA 1.1 -- Karaf and other frameworks still
// use it. Without this, the plugin generates [1.2,2).
'javax.transaction;version="[1.1,2)"',
// Also import every package referenced in the code
'*'
].join( ',' ),
// // BND Plugin instructions (for OSGi):
// 'Import-Package': [
// 'javax.security.auth;resolution:=optional',
// // Make javax.security.jacc optional and do not reference a version range (because that's what we used to do)
// 'javax.security.jacc;resolution:=optional;version=!',
// // Make javax.validation optional and do not reference a version range (because that's what we used to do)
// 'javax.validation;resolution:=optional;version=!',
// 'javax.validation.constraints;resolution:=optional;version=!',
// 'javax.validation.groups;resolution:=optional;version=!',
// 'javax.validation.metadata;resolution:=optional;version=!',
// // Make javax.enterprise optional and do not reference a version range (because that's what we used to do)
// '!javax.enterprise*',
// 'javax.enterprise.context.spi;resolution:=optional;version=!',
// 'javax.enterprise.inject.spi;resolution:=optional;version=!',
// // For JPA, we don't want to target the automatically generated range, but a specific version
// "javax.persistence;version=\"${project.jpaVersion.osgiName}\"",
// // optionals
// 'jakarta.persistence.spi;resolution:=optional',
// 'javax.management;resolution:=optional',
// 'javax.naming.event;resolution:=optional',
// 'javax.naming.spi;resolution:=optional',
// 'org.apache.tools.ant;resolution:=optional',
// 'org.apache.tools.ant.taskdefs;resolution:=optional',
// 'org.apache.tools.ant.types;resolution:=optional',
// 'javax.inject;resolution:=optional',
// 'net.bytebuddy.*;resolution:=optional',
// 'org.objectweb.jonas_tm;resolution:=optional',
// 'com.ibm.websphere.jtaextensions;resolution:=optional',
// // We must specify the version explicitly to allow Karaf
// // to use an older version of JAXB (the only one we can use in Karaf)
// "javax.xml.bind.*;version=\"${project.jaxbApiVersionOsgiRange}\"",
// // Temporarily support JTA 1.1 -- Karaf and other frameworks still
// // use it. Without this, the plugin generates [1.2,2).
// 'javax.transaction;version="[1.1,2)"',
// // Also import every package referenced in the code
// '*'
// ].join( ',' ),
'-exportcontents': [
// Legacy resource packages containing XSDs that were traditionally not exported
"!org.hibernate.xsd.cfg",

View File

@ -397,4 +397,59 @@ public final class CollectionHelper {
return map;
}
public static Map<String,String> toMap(String... pairs) {
assert pairs.length % 2 == 0;
if ( pairs.length == 2 ) {
return Collections.singletonMap( pairs[0], pairs[1] );
}
final Map<String,String> result = new HashMap<>();
applyToMap( result, pairs );
return result;
}
private static void applyToMap(Map<String,String> map, String... pairs) {
assert pairs.length % 2 == 0;
for ( int i = 0; i < pairs.length; i+=2 ) {
map.put( pairs[i], pairs[i+1] );
}
}
public static Map<String,?> toMap(Object... pairs) {
assert pairs.length % 2 == 0;
if ( pairs.length == 2 ) {
return Collections.singletonMap( (String) pairs[0], pairs[1] );
}
final Map<String,String> result = new HashMap<>();
applyToMap( result, pairs );
return result;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static void applyToMap(Map<String,?> map, Object... pairs) {
assert pairs.length % 2 == 0;
for ( int i = 0; i < pairs.length; i+=2 ) {
( (Map) map ).put( pairs[i], pairs[i+1] );
}
}
public static Properties toProperties(Object... pairs) {
final Properties properties = new Properties();
if ( pairs.length > 0 ) {
assert pairs.length % 2 == 0;
for ( int i = 0; i < pairs.length; i+=2 ) {
properties.put( pairs[i], pairs[i+1] );
}
}
return properties;
}
public static void applyToProperties(Properties properties, Object... pairs) {
assert pairs.length % 2 == 0;
for ( int i = 0; i < pairs.length; i+=2 ) {
properties.put( pairs[i], pairs[i+1] );
}
}
}

View File

@ -135,6 +135,13 @@ public enum Action {
}
}
// lastly, look at the enum name
for ( Action action : values() ) {
if ( action.name().equals( name ) ) {
return action;
}
}
throw new IllegalArgumentException( "Unrecognized JPA schema generation action value : " + value );
}

View File

@ -47,6 +47,7 @@ import static org.hibernate.cfg.AvailableSettings.JAKARTA_HBM2DDL_DROP_SOURCE;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_HBM2DDL_SCRIPTS_ACTION;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_HBM2DDL_SCRIPTS_CREATE_TARGET;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_HBM2DDL_SCRIPTS_DROP_TARGET;
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
/**
* Responsible for coordinating SchemaManagementTool execution(s) for auto-tooling whether
@ -630,71 +631,142 @@ public class SchemaManagementToolCoordinator {
}
/**
* For test use
* For test use. See {@link #interpret(Metadata, Map)} for the "real" impl
*/
@Internal
public static ActionGrouping interpret(Map configurationValues) {
Object databaseActionSetting = configurationValues.get( HBM2DDL_DATABASE_ACTION );
Object scriptsActionSetting = configurationValues.get( HBM2DDL_SCRIPTS_ACTION );
if ( databaseActionSetting == null ) {
databaseActionSetting = configurationValues.get( JAKARTA_HBM2DDL_DATABASE_ACTION );
}
if ( scriptsActionSetting == null ) {
scriptsActionSetting = configurationValues.get( JAKARTA_HBM2DDL_SCRIPTS_ACTION );
}
// interpret the JPA settings first
Action databaseAction = Action.interpretJpaSetting( databaseActionSetting );
Action scriptAction = Action.interpretJpaSetting( scriptsActionSetting );
public static ActionGrouping interpret(Map<?,?> configurationValues) {
// default to the JPA settings
Action databaseAction = determineJpaDbActionSetting( configurationValues );
Action scriptAction = determineJpaScriptActionSetting( configurationValues );
// if no JPA settings were specified, look at the legacy HBM2DDL_AUTO setting...
if ( databaseAction == Action.NONE && scriptAction == Action.NONE ) {
final Action hbm2ddlAutoAction = Action.interpretHbm2ddlSetting( configurationValues.get( HBM2DDL_AUTO ) );
if ( hbm2ddlAutoAction != Action.NONE ) {
databaseAction = hbm2ddlAutoAction;
if ( databaseAction == null && scriptAction == null ) {
final Action autoAction = determineAutoSettingImpliedAction( configurationValues, null, null );
if ( autoAction != null ) {
databaseAction = autoAction;
}
}
if ( databaseAction == null ) {
databaseAction = Action.NONE;
}
if ( scriptAction == null ) {
scriptAction = Action.NONE;
}
return new ActionGrouping( "orm", databaseAction, scriptAction );
}
private static Action determineJpaDbActionSetting(Map<?,?> configurationValues) {
return determineJpaDbActionSetting( configurationValues, null, null );
}
/**
* Exposed for tests
*/
@Internal
public static Action determineJpaDbActionSetting(
Map<?,?> configurationValues,
String contributor,
Action defaultValue) {
final String jakartaSettingName = contributor == null
? JAKARTA_HBM2DDL_DATABASE_ACTION
: JAKARTA_HBM2DDL_DATABASE_ACTION + "." + contributor;
final String javaxSettingName = contributor == null
? HBM2DDL_DATABASE_ACTION
: HBM2DDL_DATABASE_ACTION + "." + contributor;
Object databaseActionSetting = configurationValues.get( jakartaSettingName );
if ( databaseActionSetting == null ) {
databaseActionSetting = configurationValues.get( javaxSettingName );
if ( databaseActionSetting != null ) {
DEPRECATION_LOGGER.deprecatedSetting( HBM2DDL_DATABASE_ACTION, JAKARTA_HBM2DDL_DATABASE_ACTION );
}
}
return databaseActionSetting == null ? defaultValue : Action.interpretJpaSetting( databaseActionSetting );
}
private static Action determineJpaScriptActionSetting(Map<?,?> configurationValues) {
return determineJpaScriptActionSetting( configurationValues, null, null );
}
/**
* Exposed for tests
*/
@Internal
public static Action determineJpaScriptActionSetting(
Map<?,?> configurationValues,
String contributor,
Action defaultValue) {
final String jakartaSettingName = contributor == null
? JAKARTA_HBM2DDL_SCRIPTS_ACTION
: JAKARTA_HBM2DDL_SCRIPTS_ACTION + "." + contributor;
final String javaxSettingName = contributor == null
? HBM2DDL_SCRIPTS_ACTION
: HBM2DDL_SCRIPTS_ACTION + "." + contributor;
Object scriptsActionSetting = configurationValues.get( jakartaSettingName );
if ( scriptsActionSetting == null ) {
scriptsActionSetting = configurationValues.get( javaxSettingName );
if ( scriptsActionSetting != null ) {
DEPRECATION_LOGGER.deprecatedSetting( HBM2DDL_SCRIPTS_ACTION, JAKARTA_HBM2DDL_SCRIPTS_ACTION );
}
}
return scriptsActionSetting == null ? defaultValue : Action.interpretJpaSetting( scriptsActionSetting );
}
public static Action determineAutoSettingImpliedAction(Map<?,?> settings, String contributor, Action defaultValue) {
final String settingName = contributor == null
? HBM2DDL_AUTO
: HBM2DDL_AUTO + "." + contributor;
final Object scriptsActionSetting = settings.get( settingName );
if ( scriptsActionSetting == null ) {
return defaultValue;
}
return Action.interpretHbm2ddlSetting( scriptsActionSetting );
}
public static Set<ActionGrouping> interpret(Metadata metadata, Map<?,?> configurationValues) {
// these represent the base (non-contributor-specific) values
final Action rootDatabaseAction = Action.interpretJpaSetting( configurationValues.get( HBM2DDL_DATABASE_ACTION ) );
final Action rootScriptAction = Action.interpretJpaSetting( configurationValues.get( HBM2DDL_SCRIPTS_ACTION ) );
final Action rootExportAction = Action.interpretHbm2ddlSetting( configurationValues.get( HBM2DDL_AUTO ) );
final Action rootDatabaseAction = determineJpaDbActionSetting( configurationValues, null, null );
final Action rootScriptAction = determineJpaScriptActionSetting( configurationValues, null, null );
final Action rootAutoAction = determineAutoSettingImpliedAction( configurationValues, null, null );
final Set<String> contributors = metadata.getContributors();
final Set<ActionGrouping> groupings = new HashSet<>( contributors.size() );
// for each contributor, look for specific tooling config values
for ( String contributor : contributors ) {
final Object contributorDatabaseActionSetting = configurationValues.get( HBM2DDL_DATABASE_ACTION + "." + contributor );
final Object contributorScriptActionSetting = configurationValues.get( HBM2DDL_SCRIPTS_ACTION + "." + contributor );
final Object contributorExportActionSetting = configurationValues.get( HBM2DDL_AUTO + "." + contributor );
Action databaseActionToUse = determineJpaDbActionSetting( configurationValues, contributor, rootDatabaseAction );;
Action scriptActionToUse = determineJpaScriptActionSetting( configurationValues, contributor, rootScriptAction );
final Action contributorDatabaseAction = contributorDatabaseActionSetting == null
? rootDatabaseAction
: Action.interpretJpaSetting( contributorDatabaseActionSetting );
final Action contributorScriptAction = contributorScriptActionSetting == null
? rootScriptAction
: Action.interpretJpaSetting( contributorScriptActionSetting );
final Action contributorExportAction = contributorExportActionSetting == null
? rootExportAction
: Action.interpretJpaSetting( contributorExportActionSetting );
Action databaseAction = contributorDatabaseAction;
if ( databaseAction == Action.NONE && contributorScriptAction == Action.NONE ) {
if ( contributorExportAction != Action.NONE ) {
databaseAction = contributorExportAction;
if ( databaseActionToUse == null && scriptActionToUse == null ) {
// no JPA (jakarta nor javax) settings were specified, use the legacy Hibernate
// `hbm2ddl.auto` setting to possibly set the database-action
final Action contributorAutoSetting = determineAutoSettingImpliedAction( configurationValues, contributor, rootAutoAction );
if ( contributorAutoSetting != null ) {
databaseActionToUse = contributorAutoSetting;
}
}
if ( databaseAction == Action.NONE ) {
if ( databaseActionToUse == null ) {
databaseActionToUse = Action.NONE;
}
if ( scriptActionToUse == null ) {
scriptActionToUse = Action.NONE;
}
if ( databaseActionToUse == Action.NONE && scriptActionToUse == Action.NONE ) {
log.debugf( "No schema actions specified for contributor `%s`; doing nothing", contributor );
continue;
}
}
groupings.add( new ActionGrouping( contributor, databaseAction, contributorScriptAction ) );
groupings.add( new ActionGrouping( contributor, databaseActionToUse, scriptActionToUse ) );
}
return groupings;

View File

@ -7,14 +7,25 @@
package org.hibernate.orm.test.jpa.ejb3configuration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.dialect.internal.DialectResolverInitiator;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
import org.hibernate.jpa.boot.spi.Bootstrap;
import org.hibernate.orm.test.dialect.resolver.TestingDialectResolutionInfo;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.tool.schema.Action;
import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.ActionGrouping;
import org.hibernate.testing.orm.jpa.PersistenceUnitInfoAdapter;
import org.hibernate.testing.orm.junit.BaseUnitTest;
@ -203,7 +214,7 @@ public class ConfigurationObjectSettingTest {
{
builder = (EntityManagerFactoryBuilderImpl) Bootstrap.getEntityManagerFactoryBuilder(
empty,
toMap(
CollectionHelper.toMap(
jdbcUrl, urlValue,
jdbcDriver, driverValue,
jdbcUser, userValue,
@ -221,7 +232,7 @@ public class ConfigurationObjectSettingTest {
}
PersistenceUnitInfoAdapter pui = new PersistenceUnitInfoAdapter();
applyToMap(
CollectionHelper.applyToProperties(
pui.getProperties(),
jdbcUrl, urlValue,
jdbcDriver, driverValue,
@ -242,34 +253,67 @@ public class ConfigurationObjectSettingTest {
builder.cancel();
}
}
private static Map<String,String> toMap(String... pairs) {
assert pairs.length %2 == 0;
if ( pairs.length == 2 ) {
return Collections.singletonMap( pairs[0], pairs[1] );
@Test
public void testSchemaGenSettings() {
verifySchemaGenSettings(
AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION,
AvailableSettings.JAKARTA_HBM2DDL_SCRIPTS_ACTION,
AvailableSettings.JAKARTA_HBM2DDL_CREATE_SCHEMAS,
AvailableSettings.JAKARTA_HBM2DDL_DB_NAME
);
verifySchemaGenSettings(
AvailableSettings.HBM2DDL_DATABASE_ACTION,
AvailableSettings.HBM2DDL_SCRIPTS_ACTION,
AvailableSettings.HBM2DDL_CREATE_SCHEMAS,
AvailableSettings.DIALECT_DB_NAME
);
// verifySchemaGenSettingsPrecedence();
}
final Map<String,String> result = new HashMap<>();
for ( int i = 0; i < pairs.length; i+=2 ) {
result.put( pairs[i], pairs[i+1] );
}
return result;
private void verifySchemaGenSettings(
String dbActionSettingName,
String scriptActionSettingName,
String createSchemasSettingName,
String dbNameSettingName) {
final Action dbAction = Action.CREATE_ONLY;
final Action scriptAction = Action.CREATE_ONLY;
final boolean createSchemas = true;
final String dbName = "H2";
final Map<String, String> settings = CollectionHelper.toMap(
dbActionSettingName, dbAction.getExternalJpaName(),
scriptActionSettingName, scriptAction.getExternalJpaName(),
createSchemasSettingName, Boolean.toString( createSchemas ),
dbNameSettingName, dbName
);
// first verify the individual interpretations
final Action interpretedDbAction = ActionGrouping.determineJpaDbActionSetting( settings, null, null );
assertThat( interpretedDbAction ).isEqualTo( dbAction );
final Action interpretedScriptAction = ActionGrouping.determineJpaScriptActionSetting( settings, null, null );
assertThat( interpretedScriptAction ).isEqualTo( scriptAction );
// next verify the action-group determination
final ActionGrouping actionGrouping = ActionGrouping.interpret( settings );
assertThat( actionGrouping.getDatabaseAction() ).isEqualTo( dbAction );
assertThat( actionGrouping.getScriptAction() ).isEqualTo( scriptAction );
// the check above uses a "for testing only" form of what happens for "real".
// verify the "real" path as well
final Metadata metadata = new MetadataSources().addAnnotatedClass( Bell.class ).buildMetadata();
final Set<ActionGrouping> actionGroupings = ActionGrouping.interpret( metadata, settings );
assertThat( actionGroupings ).hasSize( 1 );
final ActionGrouping grouping = actionGroupings.iterator().next();
assertThat( grouping.getContributor() ).isEqualTo( "orm" );
assertThat( grouping.getDatabaseAction() ).isEqualTo( dbAction );
assertThat( grouping.getScriptAction() ).isEqualTo( scriptAction );
// verify also interpreting the db-name, etc... they are used by SF/EMF to resolve Dialect
final DialectResolver dialectResolver = new DialectResolverInitiator().initiateService( settings, (ServiceRegistryImplementor) new StandardServiceRegistryBuilder().build() );
final Dialect dialect = dialectResolver.resolveDialect( TestingDialectResolutionInfo.forDatabaseInfo( dbName ) );
assertThat( dialect ).isInstanceOf( H2Dialect.class );
}
private static void applyToMap(Map<String,String> map, String... pairs) {
assert pairs.length %2 == 0;
for ( int i = 0; i < pairs.length; i+=2 ) {
map.put( pairs[i], pairs[i+1] );
}
}
private static void applyToMap(Properties map, String... pairs) {
assert pairs.length %2 == 0;
for ( int i = 0; i < pairs.length; i+=2 ) {
map.put( pairs[i], pairs[i+1] );
}
}
}

View File

@ -0,0 +1,38 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.jpa.jakarta;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test;
/**
* Make sure {@code `jakarta.persistence.*`} settings have function precedence over
* the legacy {@link `javax.persistence.*`} counterparts
*
* @author Steve Ebersole
*/
@ServiceRegistry(
settings = {
@Setting( name = AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION, value = "create-drop" ),
@Setting( name = AvailableSettings.HBM2DDL_DATABASE_ACTION, value = "none" )
}
)
@DomainModel( annotatedClasses = SimpleEntity.class )
@SessionFactory
public class JakartaSchemaToolingSettingPrecedenceTests {
@Test
public void verifySchemaCreated(SessionFactoryScope scope) {
// the query would fail if the schema were not exported - just a smoke test
scope.inTransaction( (s) -> s.createQuery( "from SimpleEntity" ).list() );
}
}

View File

@ -0,0 +1,125 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.jpa.jakarta;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jpa.boot.spi.Bootstrap;
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
import org.hibernate.tool.schema.Action;
import org.hibernate.testing.orm.jpa.PersistenceUnitDescriptorAdapter;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.Setting;
import org.hibernate.testing.transaction.TransactionUtil2;
import org.junit.jupiter.api.Test;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_DATABASE_ACTION;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_JPA_JDBC_DRIVER;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_JPA_JDBC_PASSWORD;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_JPA_JDBC_URL;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_JPA_JDBC_USER;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_DRIVER;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_PASSWORD;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_URL;
import static org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER;
/**
* @author Steve Ebersole
*/
@ServiceRegistry(
settings = {
@Setting( name = JAKARTA_HBM2DDL_DATABASE_ACTION, value = "create-drop" )
}
)
@DomainModel( annotatedClasses = SimpleEntity.class )
@SessionFactory
public class JakartaSchemaToolingTests {
@Test
public void testSchemaCreation() {
verifySchemaCreation( JAKARTA_HBM2DDL_DATABASE_ACTION, JAKARTA_JPA_JDBC_DRIVER, JAKARTA_JPA_JDBC_URL, JAKARTA_JPA_JDBC_USER, JAKARTA_JPA_JDBC_PASSWORD );
verifySchemaCreation( HBM2DDL_DATABASE_ACTION, JPA_JDBC_DRIVER, JPA_JDBC_URL, JPA_JDBC_USER, JPA_JDBC_PASSWORD );
}
private void verifySchemaCreation(
String actionSettingName,
String driverSettingName,
String urlSettingName,
String userSettingName,
String passwordSettingName) {
final SessionFactoryImplementor sessionFactory = buildSessionFactory(
actionSettingName, Action.CREATE_DROP,
driverSettingName, Environment.getProperties().get( AvailableSettings.DRIVER ),
urlSettingName, Environment.getProperties().get( AvailableSettings.URL ),
userSettingName, Environment.getProperties().get( AvailableSettings.USER ),
passwordSettingName, Environment.getProperties().get( AvailableSettings.PASS )
);
try {
tryQuery( sessionFactory );
}
finally {
sessionFactory.close();
}
}
private void tryQuery(SessionFactoryImplementor sessionFactory) {
TransactionUtil2.inTransaction( sessionFactory, (session) -> {
// the query would fail if the schema were not exported - just a smoke test
session.createQuery( "from SimpleEntity" ).list();
});
}
@Test
public void testPrecedence() {
// make sure JAKARTA_HBM2DDL_DATABASE_ACTION (`jakarta...`) takes precedence over HBM2DDL_DATABASE_ACTION (`javax...`)
try ( SessionFactoryImplementor sessionFactory = buildSessionFactory(
JAKARTA_HBM2DDL_DATABASE_ACTION, Action.CREATE_DROP,
HBM2DDL_DATABASE_ACTION, Action.NONE,
JAKARTA_JPA_JDBC_DRIVER, Environment.getProperties().get( AvailableSettings.DRIVER ),
JAKARTA_JPA_JDBC_URL, Environment.getProperties().get( AvailableSettings.URL ),
JAKARTA_JPA_JDBC_USER, Environment.getProperties().get( AvailableSettings.USER ),
JAKARTA_JPA_JDBC_PASSWORD, Environment.getProperties().get( AvailableSettings.PASS )
) ) {
tryQuery( sessionFactory );
}
}
private SessionFactoryImplementor buildSessionFactory(Object... settingPairs) {
final Properties settings = CollectionHelper.toProperties( settingPairs );
final PersistenceUnitDescriptorAdapter puDescriptor = new PersistenceUnitDescriptorAdapter() {
@Override
public Properties getProperties() {
return settings;
}
@Override
public List<String> getManagedClassNames() {
return Collections.singletonList( SimpleEntity.class.getName() );
}
};
final EntityManagerFactoryBuilder emfBuilder = Bootstrap.getEntityManagerFactoryBuilder(
puDescriptor,
settings,
(mergedSettings) -> mergedSettings.getConfigurationValues().clear()
);
return emfBuilder.build().unwrap( SessionFactoryImplementor.class );
}
}

View File

@ -4,7 +4,7 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.jpa.xml;
package org.hibernate.orm.test.jpa.jakarta;
import java.io.IOException;
import java.io.InputStream;

View File

@ -0,0 +1,24 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.jpa.jakarta;
import jakarta.persistence.Basic;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
/**
* @author Steve Ebersole
*/
@Entity(name = "SimpleEntity")
@Table(name = "SimpleEntity")
public class SimpleEntity {
@Id
public Integer id;
@Basic
public String name;
}

View File

@ -0,0 +1,13 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
/**
* Initial tests for functional Jakarta Persistence support;
*
* @author Steve Ebersole
*/
package org.hibernate.orm.test.jpa.jakarta;