Merge remote-tracking branch 'upstream5/master' into wip/6.0_merged_4

This commit is contained in:
Andrea Boriero 2019-09-30 16:45:27 +01:00
commit 726dbeef34
27 changed files with 1608 additions and 67 deletions

View File

@ -2,7 +2,7 @@
Hibernate ORM is a library providing Object/Relational Mapping (ORM) support
to applications, libraries and frameworks.
to applications, libraries, and frameworks.
It also provides an implementation of the JPA specification, which is the standard Java specification for ORM.
@ -46,7 +46,7 @@ particular that are indispensable:
* [Gradle User Guide](https://docs.gradle.org/current/userguide/userguide_single.html) is a typical user guide in that
it follows a topical approach to describing all of the capabilities of Gradle.
* [Gradle DSL Guide](https://docs.gradle.org/current/dsl/index.html) is quite unique and excellent in quickly
* [Gradle DSL Guide](https://docs.gradle.org/current/dsl/index.html) is unique and excellent in quickly
getting up to speed on certain aspects of Gradle.
@ -54,7 +54,7 @@ Using the Gradle Wrapper
------------------------
For contributors who do not otherwise use Gradle and do not want to install it, Gradle offers a very cool
features called the wrapper. It lets you run Gradle builds without a previously installed Gradle distro in
feature called the wrapper. It lets you run Gradle builds without a previously installed Gradle distro in
a zero-conf manner. Hibernate configures the Gradle wrapper for you. If you would rather use the wrapper and
not install Gradle (or to make sure you use the version of Gradle intended for older builds) you would just use
the command `gradlew` (or `gradlew.bat`) rather than `gradle` (or `gradle.bat`) in the following discussions.
@ -80,7 +80,7 @@ sub-project and execute that task if the sub-project defines it. To execute a t
either:
1. `cd` into that module directory and execute the task
2. name the "task path". For example, in order to run the tests for the _hibernate-core_ module from the root directory you could say `gradle hibernate-core:test`
2. name the "task path". For example, to run the tests for the _hibernate-core_ module from the root directory you could say `gradle hibernate-core:test`
Common Java related tasks
------------------------
@ -115,7 +115,7 @@ Coming soon...
Using "profiles"
------------------------
The Hibernate build defines a number of database testing "profiles" in `databases.gradle`. These
The Hibernate build defines several database testing "profiles" in `databases.gradle`. These
profiles can be activated by name using the `db` build property which can be passed either as
a JVM system prop (`-D`) or as a Gradle project property (`-P`). Examples below use the Gradle
project property approach.
@ -127,7 +127,7 @@ Use the following command:
gradle clean compile -Pdb=pgsql
_*NOTE : If you are running tests against a JDBC driver that is not available via Maven central (generally due to license nonsense - Oracle, DB2, etc) be sure to add these drivers to your local Maven repo cache (~/.m2/repository) or (better) add it to a personal Maven repo server*_
_*NOTE: If you are running tests against a JDBC driver that is not available via Maven central (generally due to license nonsense - Oracle, DB2, etc) be sure to add these drivers to your local Maven repo cache (~/.m2/repository) or (better) add it to a personal Maven repo server*_
Running database-specific tests from the IDE using "profiles"
-------------------------------------------------------------

View File

@ -3,6 +3,22 @@ Hibernate 5 Changelog
Note: Please refer to JIRA to learn more about each issue.
Changes in 5.4.6.Final (September 30, 2019)
------------------------------------------------------------------------------------------------------------------------
https://hibernate.atlassian.net/projects/HHH/versions/31794/tab/release-report-done
** Bug
* [HHH-11797] - Envers Map<Enum, Entity> not auditing correctly
* [HHH-13493] - For a native query, the SessionImpl class does not call applyQuerySettingsAndHints
* [HHH-13597] - Building DatabaseInformation fails on H2 without DATABASE_TO_UPPER
* [HHH-13625] - After upgrading to 5.4.5, it's no longer possible to bootstrap Hibernate if the org.hibernate.cfg LOG is set to DEBUG
* [HHH-13645] - StatsNamedContainer#getOrCompute throws NullPointerException when computed value is null
** Improvement
* [HHH-13130] - Provide Gradle-based bytecode enhancement as a task separate from the compileJava task
Changes in 5.4.5.Final (September 17, 2019)
------------------------------------------------------------------------------------------------------------------------

View File

@ -350,7 +350,7 @@ include::{sourcedir}/polymorphism/DomainModelEntity.java[tags=entity-inheritance
====
If we have two entity mappings, a `Book` and a `Blog`,
and the `Book` entity is mapped with the
and the `Blog` entity is mapped with the
https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Polymorphism.html[`@Polymorphism`] annotation
and taking the `PolymorphismType.EXPLICIT` setting:

View File

@ -918,7 +918,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
throw new DuplicateMappingException(
String.format(
Locale.ENGLISH,
"Table [%s] contains physical column name [%s] referred to by multiple physical " +
"Table [%s] contains physical column name [%s] referred to by multiple logical " +
"column names: [%s], [%s]",
tableName,
physicalName,

View File

@ -100,7 +100,7 @@ public class H2Dialect extends Dialect {
if ( buildId >= 32 ) {
this.sequenceInformationExtractor = SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
this.querySequenceString = "select * from information_schema.sequences";
this.querySequenceString = "select * from INFORMATION_SCHEMA.sequences";
}
else {
this.sequenceInformationExtractor = SequenceInformationExtractorNoOpImpl.INSTANCE;

View File

@ -58,6 +58,7 @@ import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.internal.ProcedureCallImpl;
import org.hibernate.procedure.spi.NamedCallableQueryMemento;
import org.hibernate.query.Query;
import org.hibernate.query.hql.spi.HqlQueryImplementor;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryImplementor;
@ -625,8 +626,8 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
this
);
query.setComment( queryString );
applyQuerySettingsAndHints( query );
query.setComment( queryString );
return query;
}
@ -653,6 +654,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
try {
NativeQueryImpl query = new NativeQueryImpl( queryString, this );
query.setComment( "dynamic native SQL query" );
applyQuerySettingsAndHints( query );
return query;
}
catch (RuntimeException he) {
@ -740,7 +742,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
.getHqlQueryMemento( queryName );
if ( namedHqlDescriptor != null ) {
return namedHqlDescriptor.toQuery( this, resultType );
HqlQueryImplementor query = namedHqlDescriptor.toQuery( this, resultType );
query.setComment( "dynamic native SQL query" );
applyQuerySettingsAndHints( query );
return query;
}
// otherwise, see if it is a named native query
@ -749,7 +754,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
.getNativeQueryMemento( queryName );
if ( namedNativeDescriptor != null ) {
return namedNativeDescriptor.toQuery( this, resultType );
NativeQueryImplementor query = namedNativeDescriptor.toQuery( this, resultType );
query.setComment( "dynamic native SQL query" );
applyQuerySettingsAndHints( query );
return query;
}
// todo (6.0) : allow this for named stored procedures as well?

View File

@ -6,8 +6,6 @@
*/
package org.hibernate.stat.internal;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
@ -71,12 +69,21 @@ final class StatsNamedContainer<V> {
}
else {
final V v2 = function.apply( key );
final V v3 = map.putIfAbsent( key, v2 );
if ( v3 == null ) {
return v2;
//Occasionally a function might return null. We can't store a null in the CHM,
// so a placeholder would be required to implement that, but we prefer to just keep this
// situation as slightly sub-optimal so to not make the code more complex just to handle the exceptional case:
// null values are assumed to be rare enough for this not being worth it.
if ( v2 == null ) {
return null;
}
else {
return v3;
final V v3 = map.putIfAbsent( key, v2 );
if ( v3 == null ) {
return v2;
}
else {
return v3;
}
}
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.jpa.test.lock;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.jpa.QueryHints;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.query.NativeQuery;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.util.ExceptionUtil;
import org.hibernate.type.IntegerType;
import org.junit.Test;
import java.util.Map;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Vlad Mihalcea
*/
@RequiresDialect(PostgreSQL82Dialect.class)
@TestForIssue( jiraKey = "HHH-13493")
public class NativeSQLQueryTimeoutTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected void addConfigOptions(Map options) {
options.put( QueryHints.SPEC_HINT_TIMEOUT, "500" );
}
@Test
public void test(){
doInJPA( this::entityManagerFactory, entityManager -> {
try {
entityManager.createNativeQuery(
"select 1 " +
"from pg_sleep(2) "
)
.getResultList();
fail("Should have thrown lock timeout exception!");
} catch (Exception expected) {
assertTrue(
ExceptionUtil.rootCause(expected)
.getMessage().contains("canceling statement due to user request")
);
}
} );
}
@Override
public Class[] getAnnotatedClasses() {
return new Class[] {
};
}
}

View File

@ -0,0 +1,405 @@
/*
* 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.bootstrap;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.sql.DataSource;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.env.ConnectionProviderBuilder;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.util.jpa.DelegatingPersistenceUnitInfo;
import org.hibernate.testing.util.jpa.PersistenceUnitInfoAdapter;
import org.hibernate.testing.util.jpa.PersistenceUnitInfoPropertiesWrapper;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Steve Ebersole
*/
public class PersistenceUnitOverridesTests extends BaseUnitTestCase {
@Test
public void testCustomProviderPassingIntegrationJpaJdbcOverrides() {
PersistenceProvider provider = new HibernatePersistenceProvider() {
@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integrationOverrides) {
return super.createContainerEntityManagerFactory(
new DelegatingPersistenceUnitInfo( info ) {
@Override
public Properties getProperties() {
// use the "db1" connection settings keyed by the JPA property names (org.hibernate.cfg.AvailableSettings.JPA_JDBC_DRIVER, e.g.)
final Properties properties = new Properties();
properties.putAll( info.getProperties() );
properties.putAll( ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db1" ) );
return properties;
}
},
integrationOverrides
);
}
};
// however, use the "db2" JPA connection settings which should override the persistence unit values
final Map integrationOverrides = ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db2" );
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
new PersistenceUnitInfoPropertiesWrapper(),
integrationOverrides
);
try {
final Map<String, Object> properties = emf.getProperties();
final Object hibernateJdbcDriver = properties.get( AvailableSettings.URL );
assertThat( hibernateJdbcDriver, notNullValue() );
final Object jpaJdbcDriver = properties.get( AvailableSettings.JPA_JDBC_URL );
assertThat( (String) jpaJdbcDriver, containsString( "db2" ) );
}
finally {
emf.close();
}
}
@Test
public void testPassingIntegrationJpaJdbcOverridesForJtaDataSourceProperty() {
PersistenceProvider provider = new HibernatePersistenceProvider() {
@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integrationOverrides) {
return super.createContainerEntityManagerFactory(
new DelegatingPersistenceUnitInfo( info ) {
// inject a JPA JTA DataSource setting into the PU
final DataSource puDataSource;
final Properties puProperties;
{
puDataSource = new DataSourceImpl( "puDataSource" );
puProperties = new Properties();
puProperties.putAll( info.getProperties() );
puProperties.put( AvailableSettings.JPA_JTA_DATASOURCE, puDataSource );
}
@Override
public Properties getProperties() {
return puProperties;
}
},
integrationOverrides
);
}
};
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
new PersistenceUnitInfoAdapter(),
// however, provide JPA connection settings as "integration settings", which according to JPA spec should override the persistence unit values.
// - note that it is unclear in the spec whether JDBC value in the integration settings should override
// a JTA DataSource (nor the reverse). However, that is a useful thing to support
ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db2" )
);
try {
final Map<String, Object> properties = emf.getProperties();
final Object hibernateJdbcDriver = properties.get( AvailableSettings.URL );
assertThat( hibernateJdbcDriver, notNullValue() );
final Object jpaJdbcDriver = properties.get( AvailableSettings.JPA_JDBC_URL );
assertThat( (String) jpaJdbcDriver, containsString( "db2" ) );
// see if the values had the affect to adjust the `ConnectionProvider` used
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
.getServiceRegistry()
.getService( ConnectionProvider.class );
assertThat( connectionProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
}
finally {
emf.close();
}
}
@Test
@FailureExpected(
jiraKey = "HHH-12858",
message = "Even though the JDBC settings override a DataSource *property*, it" +
" does not override a DataSource defined using the dedicated persistence.xml element"
)
public void testPassingIntegrationJpaJdbcOverridesForJtaDataSourceElement() {
PersistenceProvider provider = new HibernatePersistenceProvider() {
@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integrationOverrides) {
return super.createContainerEntityManagerFactory(
new DelegatingPersistenceUnitInfo( info ) {
// inject a JPA JTA DataSource setting into the PU
final DataSource puDataSource;
{
puDataSource = new DataSourceImpl( "puDataSource" );
}
@Override
public DataSource getJtaDataSource() {
return puDataSource;
}
},
integrationOverrides
);
}
};
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
new PersistenceUnitInfoAdapter(),
// however, provide JPA connection settings as "integration settings", which according to JPA spec should override the persistence unit values.
// - note that it is unclear in the spec whether JDBC value in the integration settings should override
// a JTA DataSource (nor the reverse). However, that is a useful thing to support
ConnectionProviderBuilder.getJpaConnectionProviderProperties( "db2" )
);
try {
final Map<String, Object> properties = emf.getProperties();
final Object hibernateJdbcDriver = properties.get( AvailableSettings.URL );
assertThat( hibernateJdbcDriver, notNullValue() );
final Object jpaJdbcDriver = properties.get( AvailableSettings.JPA_JDBC_URL );
assertThat( (String) jpaJdbcDriver, containsString( "db2" ) );
// see if the values had the affect to adjust the `ConnectionProvider` used
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
.getServiceRegistry()
.getService( ConnectionProvider.class );
assertThat( connectionProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
}
finally {
emf.close();
}
}
@Test
@FailureExpected(
jiraKey = "HHH-12858",
message = "So it appears any use of the persistence.xml `jta-data-source` or `non-jta-data-source` " +
"have precedence over integration settings, which is also incorrect"
)
public void testPassingIntegrationJpaDataSourceOverrideForJtaDataSourceElement() {
final DataSource puDataSource = new DataSourceImpl( "puDataSource" );
final DataSource integrationDataSource = new DataSourceImpl( "integrationDataSource" );
PersistenceProvider provider = new HibernatePersistenceProvider() {
@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map integrationOverrides) {
return super.createContainerEntityManagerFactory(
new DelegatingPersistenceUnitInfo( info ) {
@Override
public DataSource getJtaDataSource() {
// pretend the DataSource was defined using the `jta-data-source` element in persistence.xml
// - as opposed using `javax.persistence.jtaDataSource` under the `properties` element
return puDataSource;
}
},
integrationOverrides
);
}
};
final Map integrationOverrides = new HashMap();
//noinspection unchecked
integrationOverrides.put( AvailableSettings.JPA_JTA_DATASOURCE, integrationDataSource );
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
new PersistenceUnitInfoAdapter(),
integrationOverrides
);
try {
final Map<String, Object> properties = emf.getProperties();
final Object datasource = properties.get( AvailableSettings.JPA_JTA_DATASOURCE );
assertThat( datasource, is( integrationDataSource ) );
// see if the values had the affect to adjust the `ConnectionProvider` used
final ConnectionProvider connectionProvider = emf.unwrap( SessionFactoryImplementor.class )
.getServiceRegistry()
.getService( ConnectionProvider.class );
assertThat( connectionProvider, instanceOf( DatasourceConnectionProviderImpl.class ) );
final DatasourceConnectionProviderImpl datasourceConnectionProvider = (DatasourceConnectionProviderImpl) connectionProvider;
assertThat( datasourceConnectionProvider.getDataSource(), is( integrationDataSource ) );
}
finally {
emf.close();
}
}
@Test
@FailureExpected( jiraKey = "HHH-12858", message = "regression - fix" )
public void testIntegrationOverridesOfPersistenceXmlDataSource() {
// mimics a DataSource defined in the persistence.xml
final DataSourceImpl dataSource = new DataSourceImpl( "puDataSource" );
final PersistenceUnitInfoAdapter info = new PersistenceUnitInfoAdapter() {
@Override
public DataSource getNonJtaDataSource() {
return dataSource;
}
};
// Now create "integration Map" that overrides the DataSource to use
final DataSource override = new DataSourceImpl( "integrationDataSource" );
final Map<String,Object> integrationSettings = new HashMap<>();
integrationSettings.put( AvailableSettings.JPA_NON_JTA_DATASOURCE, override );
final PersistenceProvider provider = new HibernatePersistenceProvider();
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
info,
integrationSettings
);
try {
final Map<String, Object> properties = emf.getProperties();
assertThat( properties.get( AvailableSettings.JPA_NON_JTA_DATASOURCE ), notNullValue() );
assertThat( properties.get( AvailableSettings.JPA_NON_JTA_DATASOURCE ), is( override ) );
final SessionFactoryImplementor sessionFactory = emf.unwrap( SessionFactoryImplementor.class );
final ConnectionProvider connectionProvider = sessionFactory.getServiceRegistry().getService( ConnectionProvider.class );
assertThat( connectionProvider, instanceOf( DatasourceConnectionProviderImpl.class ) );
final DatasourceConnectionProviderImpl dsProvider = (DatasourceConnectionProviderImpl) connectionProvider;
assertThat( dsProvider.getDataSource(), is( override ) );
}
finally {
emf.close();
}
}
@Test
@FailureExpected( jiraKey = "HHH-12858", message = "regression - fix" )
public void testIntegrationOverridesOfPersistenceXmlDataSourceWithDriverManagerInfo() {
// mimics a DataSource defined in the persistence.xml
final DataSourceImpl dataSource = new DataSourceImpl( "puDataSource" );
final PersistenceUnitInfoAdapter info = new PersistenceUnitInfoAdapter() {
@Override
public DataSource getNonJtaDataSource() {
return dataSource;
}
};
final Map<String,Object> integrationSettings = new HashMap<>();
integrationSettings.put( AvailableSettings.JPA_JDBC_DRIVER, ConnectionProviderBuilder.DRIVER );
integrationSettings.put( AvailableSettings.JPA_JDBC_URL, ConnectionProviderBuilder.URL );
integrationSettings.put( AvailableSettings.JPA_JDBC_USER, ConnectionProviderBuilder.USER );
integrationSettings.put( AvailableSettings.JPA_JDBC_PASSWORD, ConnectionProviderBuilder.PASS );
final PersistenceProvider provider = new HibernatePersistenceProvider();
final EntityManagerFactory emf = provider.createContainerEntityManagerFactory(
info,
integrationSettings
);
final SessionFactoryImplementor sessionFactory = emf.unwrap( SessionFactoryImplementor.class );
final ConnectionProvider connectionProvider = sessionFactory.getServiceRegistry().getService( ConnectionProvider.class );
assertThat( connectionProvider, instanceOf( DriverManagerConnectionProviderImpl.class ) );
}
private static class DataSourceImpl implements DataSource {
private final String id;
private final DriverManagerConnectionProviderImpl connectionProvider;
private PrintWriter printWriter;
DataSourceImpl(String id) {
this.id = id;
connectionProvider = new DriverManagerConnectionProviderImpl();
connectionProvider.configure( ConnectionProviderBuilder.getConnectionProviderProperties() );
printWriter = null;
}
public String getId() {
return id;
}
@Override
public Connection getConnection() throws SQLException {
return connectionProvider.getConnection();
}
@Override
public Connection getConnection(String username, String password) {
throw new UnsupportedOperationException();
}
@Override
public PrintWriter getLogWriter() {
return printWriter;
}
@Override
public void setLogWriter(PrintWriter out) {
this.printWriter = out;
}
@Override
public void setLoginTimeout(int seconds) {
}
@Override
public int getLoginTimeout() {
return -1;
}
@Override
public Logger getParentLogger() {
return Logger.getGlobal();
}
@Override
public <T> T unwrap(Class<T> iface) {
//noinspection unchecked
return (T) this;
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return iface.isAssignableFrom( getClass() );
}
@Override
public String toString() {
return "DataSourceImpl(" + id + ")";
}
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.bootstrap;
import java.util.Properties;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.tool.schema.Action;
import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Steve Ebersole
*/
public class SchemaToolingAutoActionTests {
@Test
public void testLegacySettingAsAction() {
final Properties props = new Properties();
props.put( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP );
final SchemaManagementToolCoordinator.ActionGrouping actionGrouping = SchemaManagementToolCoordinator.ActionGrouping.interpret( props );
assertThat( actionGrouping.getDatabaseAction(), is( Action.CREATE_DROP ) );
}
}

View File

@ -0,0 +1,11 @@
/*
* 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
*/
/**
* Tests for Hibernate bootstrapping Hibernate
*/
package org.hibernate.orm.test.bootstrap;

View File

@ -0,0 +1,30 @@
/*
* 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.stat.internal;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.junit.Assert.assertNull;
@TestForIssue(jiraKey = "HHH-13645")
public class StatsNamedContainerNullComputedValueTest {
@Test
public void testNullComputedValue() {
final StatsNamedContainer statsNamedContainer = new StatsNamedContainer<Integer>();
assertNull(
statsNamedContainer.getOrCompute(
"key",
v -> {
return null;
}
)
);
}
}

View File

@ -0,0 +1,204 @@
/*
* 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.test.bytecode.enhancement.lazy.proxy;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.Hibernate;
import org.hibernate.annotations.LazyToOne;
import org.hibernate.annotations.LazyToOneOption;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Gail Badner
*/
@TestForIssue( jiraKey = "HHH-13640" )
@RunWith(BytecodeEnhancerRunner.class)
public class LazyToOnesProxyWithSubclassesTest extends BaseNonConfigCoreFunctionalTestCase {
@Override
protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) {
super.configureStandardServiceRegistryBuilder( ssrb );
ssrb.applySetting( AvailableSettings.ALLOW_ENHANCEMENT_AS_PROXY, "true" );
}
@Override
protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) {
super.configureSessionFactoryBuilder( sfb );
sfb.applyStatisticsSupport( true );
sfb.applySecondLevelCacheSupport( false );
sfb.applyQueryCacheSupport( false );
}
@Override
protected void applyMetadataSources(MetadataSources sources) {
super.applyMetadataSources( sources );
sources.addAnnotatedClass( Animal.class );
sources.addAnnotatedClass( Primate.class );
sources.addAnnotatedClass( Human.class );
sources.addAnnotatedClass( OtherEntity.class );
}
@Test
@FailureExpected( jiraKey = "HHH-13640")
public void testNewProxyAssociation() {
inTransaction(
session -> {
Human human = new Human( "A Human" );
OtherEntity otherEntity = new OtherEntity( "test1" );
otherEntity.animal = human;
session.persist( human );
session.persist( otherEntity );
}
);
inSession(
session -> {
final OtherEntity otherEntity = session.get( OtherEntity.class, "test1" );
assertTrue( Hibernate.isPropertyInitialized( otherEntity, "animal" ) );
assertFalse( Hibernate.isInitialized( otherEntity.animal ) );
Animal animal = session.load( Animal.class, "A Human" );
assertFalse( Hibernate.isInitialized( animal ) );
}
);
}
@Test
@FailureExpected( jiraKey = "HHH-13640")
public void testReusedProxyAssociation() {
inTransaction(
session -> {
Human human = new Human( "A Human" );
OtherEntity otherEntity = new OtherEntity( "test1" );
otherEntity.animal = human;
otherEntity.primate = human;
session.persist( human );
session.persist( otherEntity );
}
);
inSession(
session -> {
final OtherEntity otherEntity = session.get( OtherEntity.class, "test1" );
assertTrue( Hibernate.isPropertyInitialized( otherEntity, "animal" ) );
assertFalse( Hibernate.isInitialized( otherEntity.animal ) );
assertTrue( Hibernate.isPropertyInitialized( otherEntity, "primate" ) );
assertFalse( Hibernate.isInitialized( otherEntity.primate ) );
}
);
}
@After
public void cleanUpTestData() {
inTransaction(
session -> {
session.createQuery( "delete from OtherEntity" ).executeUpdate();
session.createQuery( "delete from Human" ).executeUpdate();
session.createQuery( "delete from Primate" ).executeUpdate();
session.createQuery( "delete from Animal" ).executeUpdate();
}
);
}
@Entity(name = "Animal")
@Table(name = "Animal")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public static abstract class Animal {
@Id
private String name;
public String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
}
@Entity(name = "Primate")
@Table(name = "Primate")
public static class Primate extends Animal {
public Primate(String name) {
this();
setName( name );
}
protected Primate() {
// this form used by Hibernate
}
}
@Entity(name = "Human")
@Table(name = "Human")
public static class Human extends Primate {
public Human(String name) {
this();
setName( name );
}
protected Human() {
// this form used by Hibernate
}
}
@Entity(name = "OtherEntity")
@Table(name = "OtherEntity")
public static class OtherEntity {
@Id
private String id;
@ManyToOne(fetch = FetchType.LAZY)
@LazyToOne(LazyToOneOption.NO_PROXY)
protected Animal animal = null;
@ManyToOne(fetch = FetchType.LAZY)
@LazyToOne(LazyToOneOption.NO_PROXY)
protected Primate primate = null;
@ManyToOne(fetch = FetchType.LAZY)
@LazyToOne(LazyToOneOption.NO_PROXY)
protected Human human = null;
protected OtherEntity() {
// this form used by Hibernate
}
public OtherEntity(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
}

View File

@ -0,0 +1,58 @@
package org.hibernate.test.schemaupdate;
import java.util.EnumSet;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.After;
import org.junit.Test;
@RequiresDialect(H2Dialect.class)
@TestForIssue(jiraKey = "HHH-13597")
public class H2DialectDataBaseToUpperTest extends BaseUnitTestCase {
private StandardServiceRegistry ssr;
private MetadataImplementor metadata;
@Test
public void hibernateShouldStartUpWithH2AutoUpdateAndDatabaseToUpperFalse() {
setUp( "false" );
new SchemaUpdate().setHaltOnError( true )
.execute( EnumSet.of( TargetType.DATABASE ), metadata );
}
@Test
public void hibernateShouldStartUpWithH2AutoUpdateAndDatabaseToUpperTrue() {
setUp( "true" );
new SchemaUpdate().setHaltOnError( true )
.execute( EnumSet.of( TargetType.DATABASE ), metadata );
}
private void setUp(String databaseToUpper) {
ssr = new StandardServiceRegistryBuilder()
.applySetting(
AvailableSettings.URL,
"jdbc:h2:mem:databaseToUpper;DATABASE_TO_UPPER=" + databaseToUpper
)
.build();
final MetadataSources metadataSources = new MetadataSources( ssr );
metadata = (MetadataImplementor) metadataSources.buildMetadata();
}
@After
public void tearDown() {
if ( ssr != null ) {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.test.stats;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertNull;
/**
* @author Gail Badner
*/
public class StatisticsWithNoQueryCachingTest extends BaseCoreFunctionalTestCase {
@Override
protected void configure(Configuration configuration) {
configuration.setProperty( AvailableSettings.USE_SECOND_LEVEL_CACHE, "true" );
configuration.setProperty( AvailableSettings.USE_QUERY_CACHE, "false" );
}
@Test
@TestForIssue( jiraKey = "HHH-13645")
public void testUncachedRegion() {
final Statistics statistics = sessionFactory().getStatistics();
assertNull( statistics.getCacheRegionStatistics( "hibernate.test.unknown" ) );
}
}

View File

@ -20,6 +20,7 @@ import org.hibernate.envers.configuration.internal.metadata.reader.ComponentAudi
import org.hibernate.envers.configuration.internal.metadata.reader.PropertyAuditingData;
import org.hibernate.envers.internal.EnversMessageLogger;
import org.hibernate.envers.internal.tools.MappingTools;
import org.hibernate.envers.internal.tools.StringTools;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.List;
import org.hibernate.mapping.PersistentClass;
@ -112,6 +113,12 @@ public class ClassesAuditingData {
}
}
if ( propertyAuditingData.getMapKeyEnumType() != null ) {
final String referencedEntityName = MappingTools.getReferencedEntityName( property.getValue() );
final ClassAuditingData referencedAuditingData = entityNameToAuditingData.get( referencedEntityName );
addMapEnumeratedKey( property.getValue(), property.getPropertyAccessorName(), referencedAuditingData );
}
// HHH-9108
// Added support to handle nested property calculations for components.
// This is useful for AuditMappedBy inside an Embeddable that holds a collection of entities.
@ -166,6 +173,30 @@ public class ClassesAuditingData {
}
}
private void addMapEnumeratedKey(Value value, String propertyAccessorName, ClassAuditingData classAuditingData) {
if ( value instanceof org.hibernate.mapping.Map ) {
final Value indexValue = ( (org.hibernate.mapping.Map) value ).getIndex();
if ( indexValue != null && indexValue.getColumnIterator().hasNext() ) {
final String indexColumnName = indexValue.getColumnIterator().next().getText();
if ( !StringTools.isEmpty( indexColumnName ) ) {
final PropertyAuditingData propertyAuditingData = new PropertyAuditingData(
indexColumnName,
propertyAccessorName,
ModificationStore.FULL,
RelationTargetAuditMode.AUDITED,
null,
null,
true,
true,
indexValue
);
classAuditingData.addPropertyAuditingData( indexColumnName, propertyAuditingData );
}
}
}
}
private void forcePropertyInsertable(
ClassAuditingData classAuditingData, String propertyName,
String entityName, String referencedEntityName) {

View File

@ -16,6 +16,7 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.persistence.EnumType;
import javax.persistence.JoinColumn;
import org.dom4j.Element;
@ -42,6 +43,7 @@ import org.hibernate.envers.internal.entities.mapper.relation.ListCollectionMapp
import org.hibernate.envers.internal.entities.mapper.relation.MapCollectionMapper;
import org.hibernate.envers.internal.entities.mapper.relation.MiddleComponentData;
import org.hibernate.envers.internal.entities.mapper.relation.MiddleIdData;
import org.hibernate.envers.internal.entities.mapper.relation.MiddleMapKeyEnumeratedComponentMapper;
import org.hibernate.envers.internal.entities.mapper.relation.SortedMapCollectionMapper;
import org.hibernate.envers.internal.entities.mapper.relation.SortedSetCollectionMapper;
import org.hibernate.envers.internal.entities.mapper.relation.ToOneIdMapper;
@ -64,7 +66,6 @@ import org.hibernate.envers.internal.tools.MappingTools;
import org.hibernate.envers.internal.tools.ReflectionTools;
import org.hibernate.envers.internal.tools.StringTools;
import org.hibernate.envers.internal.tools.Tools;
import org.hibernate.mapping.Bag;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.IndexedCollection;
@ -215,7 +216,8 @@ public final class CollectionMetadataGenerator {
// in a join table, so the prefix value is arbitrary).
final MiddleIdData referencedIdData = createMiddleIdData(
referencedIdMapping,
null, referencedEntityName
null,
referencedEntityName
);
// Generating the element mapping.
@ -523,7 +525,8 @@ public final class CollectionMetadataGenerator {
if ( propertyValue instanceof IndexedCollection ) {
final IndexedCollection indexedValue = (IndexedCollection) propertyValue;
final String mapKey = propertyAuditingData.getMapKey();
if ( mapKey == null ) {
final EnumType mapKeyEnumType = propertyAuditingData.getMapKeyEnumType();
if ( mapKey == null && mapKeyEnumType == null ) {
// This entity doesn't specify a javax.persistence.MapKey. Mapping it to the middle entity.
return addValueToMiddleTable(
indexedValue.getIndex(),
@ -534,6 +537,15 @@ public final class CollectionMetadataGenerator {
true
);
}
else if ( mapKeyEnumType != null ) {
final IdMappingData referencedIdMapping = mainGenerator.getEntitiesConfigurations()
.get( referencedEntityName ).getIdMappingData();
final int currentIndex = queryGeneratorBuilder == null ? 0 : queryGeneratorBuilder.getCurrentIndex();
return new MiddleComponentData(
new MiddleMapKeyEnumeratedComponentMapper( propertyAuditingData.getName() ),
currentIndex
);
}
else {
final IdMappingData referencedIdMapping = mainGenerator.getEntitiesConfigurations()
.get( referencedEntityName ).getIdMappingData();

View File

@ -19,6 +19,7 @@ import javax.persistence.ElementCollection;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.MapKey;
import javax.persistence.MapKeyEnumerated;
import javax.persistence.OneToMany;
import javax.persistence.Version;
@ -640,6 +641,12 @@ public class AuditedPropertiesReader {
if ( mapKey != null ) {
propertyData.setMapKey( mapKey.name() );
}
else {
final MapKeyEnumerated mapKeyEnumerated = property.getAnnotation( MapKeyEnumerated.class );
if ( mapKeyEnumerated != null ) {
propertyData.setMapKeyEnumType( mapKeyEnumerated.value() );
}
}
}
private void addPropertyJoinTables(XProperty property, PropertyAuditingData propertyData) {

View File

@ -9,6 +9,8 @@ package org.hibernate.envers.configuration.internal.metadata.reader;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EnumType;
import org.hibernate.envers.AuditJoinTable;
import org.hibernate.envers.AuditOverride;
import org.hibernate.envers.AuditOverrides;
@ -28,6 +30,7 @@ public class PropertyAuditingData {
private String beanName;
private ModificationStore store;
private String mapKey;
private EnumType mapKeyEnumType;
private AuditJoinTable joinTable;
private String accessType;
private final List<AuditOverride> auditJoinTableOverrides = new ArrayList<>( 0 );
@ -126,6 +129,14 @@ public class PropertyAuditingData {
this.mapKey = mapKey;
}
public EnumType getMapKeyEnumType() {
return mapKeyEnumType;
}
public void setMapKeyEnumType(EnumType mapKeyEnumType) {
this.mapKeyEnumType = mapKeyEnumType;
}
public AuditJoinTable getJoinTable() {
return joinTable;
}

View File

@ -0,0 +1,55 @@
/*
* 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.envers.internal.entities.mapper.relation;
import java.util.Map;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.internal.entities.EntityInstantiator;
import org.hibernate.envers.internal.entities.mapper.relation.component.MiddleComponentMapper;
import org.hibernate.envers.internal.tools.query.Parameters;
/**
* A {@link MiddleComponentMapper} specifically for {@link javax.persistence.MapKeyEnumerated}.
*
* @author Chris Cranford
*/
public class MiddleMapKeyEnumeratedComponentMapper implements MiddleComponentMapper {
private final String propertyName;
public MiddleMapKeyEnumeratedComponentMapper(String propertyPrefix) {
this.propertyName = propertyPrefix + "_KEY";
}
@Override
public Object mapToObjectFromFullMap(
EntityInstantiator entityInstantiator,
Map<String, Object> data,
Object dataObject,
Number revision) {
return data.get( propertyName );
}
@Override
public void mapToMapFromObject(
SessionImplementor session,
Map<String, Object> idData,
Map<String, Object> data,
Object obj) {
idData.put( propertyName, obj );
}
@Override
public void addMiddleEqualToQuery(
Parameters parameters,
String idPrefix1,
String prefix1,
String idPrefix2,
String prefix2) {
throw new UnsupportedOperationException( "Cannot use this mapper with a middle table!" );
}
}

View File

@ -0,0 +1,219 @@
/*
* 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.envers.test.integration.collection.mapkey;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MapKeyEnumerated;
import javax.persistence.OneToMany;
import org.hibernate.envers.Audited;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.Priority;
import org.hibernate.envers.test.tools.TestTools;
import org.junit.Test;
import org.hibernate.testing.TestForIssue;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
/**
* @author Chris Cranford
*/
@TestForIssue(jiraKey = "HHH-11797")
public class MapKeyEnumeratedTest extends BaseEnversJPAFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { TestEntity.class, MapEntity.class };
}
@Test
@Priority(10)
public void initData() {
// Revision 1
doInJPA( this::entityManagerFactory, entityManager -> {
final MapEntity map = new MapEntity( "Map1" );
map.setId( 1 );
final TestEntity test = new TestEntity();
test.setId( 1 );
test.addMapKeyAssociation( TestEnum.ONE, map );
entityManager.persist( test );
entityManager.persist( map );
} );
// Revision 2
doInJPA( this::entityManagerFactory, entityManager -> {
final MapEntity map = new MapEntity( "Map2" );
map.setId( 2 );
final TestEntity test = entityManager.find( TestEntity.class, 1 );
test.addMapKeyAssociation( TestEnum.TWO, map );
entityManager.persist( map );
entityManager.merge( test );
} );
// Revision 3
doInJPA( this::entityManagerFactory, entityManager -> {
final TestEntity test = entityManager.find( TestEntity.class, 1 );
final MapEntity map = test.removeMapKeyAssociation( TestEnum.ONE );
entityManager.remove( map );
entityManager.merge( test );
} );
// Revision 4
doInJPA( this::entityManagerFactory, entityManager -> {
final TestEntity test = entityManager.find( TestEntity.class, 1 );
final MapEntity map = test.removeMapKeyAssociation( TestEnum.TWO );
entityManager.remove( map );
entityManager.merge( test );
} );
}
@Test
public void testRevisionNumberHistory() {
assertEquals( Arrays.asList( 1, 2, 3, 4 ), getAuditReader().getRevisions( TestEntity.class, 1 ) );
assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( MapEntity.class, 1 ) );
assertEquals( Arrays.asList( 2, 4 ), getAuditReader().getRevisions( MapEntity.class, 2 ) );
}
@Test
public void testRevisionHistory() {
final TestEntity rev1 = getAuditReader().find( TestEntity.class, 1, 1 );
assertEquals( 1, rev1.getMapEntityMap().size() );
assertEquals( TestEnum.ONE, rev1.getMapEntityMap().keySet().iterator().next() );
final TestEntity rev2 = getAuditReader().find( TestEntity.class, 1, 2 );
assertEquals( 2, rev2.getMapEntityMap().size() );
assertEquals( TestTools.makeSet( TestEnum.ONE, TestEnum.TWO ), rev2.getMapEntityMap().keySet() );
assertEquals( TestTools.makeSet( 1, 2 ), rev2.getMapEntityMap().values().stream().map( MapEntity::getId ).collect( Collectors.toSet() ) );
final TestEntity rev3 = getAuditReader().find( TestEntity.class, 1, 3 );
assertEquals( 1, rev3.getMapEntityMap().size() );
assertEquals( TestTools.makeSet( TestEnum.TWO ), rev3.getMapEntityMap().keySet() );
assertEquals( TestTools.makeSet( 2 ), rev3.getMapEntityMap().values().stream().map( MapEntity::getId ).collect( Collectors.toSet() ) );
final TestEntity rev4 = getAuditReader().find( TestEntity.class, 1, 4 );
assertEquals( 0, rev4.getMapEntityMap().size() );
}
public enum TestEnum {
ONE,
TWO
}
@Entity(name = "TestEntity")
@Audited
public static class TestEntity {
@Id
private Integer id;
@OneToMany(mappedBy = "testEntity")
@MapKeyEnumerated(EnumType.STRING)
private Map<TestEnum, MapEntity> mapEntityMap = new HashMap<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Map<TestEnum, MapEntity> getMapEntityMap() {
return mapEntityMap;
}
public void setMapEntityMap(Map<TestEnum, MapEntity> mapEntityMap) {
this.mapEntityMap = mapEntityMap;
}
@Override
public String toString() {
return "TestEntity{" +
"id=" + id +
", mapEntityMap=" + mapEntityMap +
'}';
}
public void addMapKeyAssociation(TestEnum key, MapEntity value) {
mapEntityMap.put( key, value );
value.setTestEntity( this );
}
public MapEntity removeMapKeyAssociation(TestEnum key) {
final MapEntity value = mapEntityMap.get( key );
value.setTestEntity( null );
mapEntityMap.remove( key );
return value;
}
}
@Entity(name = "MapEntity")
@Audited
public static class MapEntity {
@Id
private Integer id;
@ManyToOne(optional = false)
private TestEntity testEntity;
private String data;
MapEntity() {
}
MapEntity(String data) {
this.data = data;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public TestEntity getTestEntity() {
return testEntity;
}
public void setTestEntity(TestEntity testEntity) {
this.testEntity = testEntity;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
@Override
public String toString() {
return "MapEntity{" +
"id=" + id +
", data=" + data +
", testEntity=" + ( testEntity == null ? null : testEntity.getId() ) +
'}';
}
}
}

View File

@ -6,25 +6,15 @@
*/
package org.hibernate.testing.env;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import javax.sql.DataSource;
import javassist.scopedpool.SoftValueHashMap;
import org.hibernate.annotations.common.reflection.ReflectionUtil;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
@ -38,27 +28,42 @@ import org.hibernate.testing.DialectCheck;
*
* @author Steve Ebersole
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public class ConnectionProviderBuilder implements DialectCheck {
public static final String DRIVER = "org.h2.Driver";
public static final String DATA_SOURCE = "org.h2.jdbcx.JdbcDataSource";
// public static final String URL = "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1;MVCC=TRUE";
public static final String URL = "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1";
public static final String URL_FORMAT = "jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1";
public static final String URL = URL_FORMAT;
public static final String USER = "sa";
public static final String PASS = "";
public static Properties getConnectionProviderProperties(String dbName) {
Properties props = new Properties( null );
props.put( Environment.DRIVER, DRIVER );
props.put( Environment.URL, String.format( URL, dbName ) );
props.put( Environment.URL, String.format( URL_FORMAT, dbName ) );
props.put( Environment.USER, USER );
props.put( Environment.PASS, PASS );
return props;
}
public static Properties getJpaConnectionProviderProperties(String dbName) {
Properties props = new Properties( null );
props.put( Environment.JPA_JDBC_DRIVER, DRIVER );
props.put( Environment.JPA_JDBC_URL, String.format( URL_FORMAT, dbName ) );
props.put( Environment.JPA_JDBC_USER, USER );
props.put( Environment.JPA_JDBC_PASSWORD, PASS );
return props;
}
public static Properties getConnectionProviderProperties() {
return getConnectionProviderProperties( "db1" );
}
public static Properties getJpaConnectionProviderProperties() {
return getJpaConnectionProviderProperties( "db1" );
}
public static DriverManagerConnectionProviderImpl buildConnectionProvider() {
return buildConnectionProvider( false );
}
@ -133,7 +138,7 @@ public class ConnectionProviderBuilder implements DialectCheck {
return connectionProxy;
}
private class ConnectionInvocationHandler implements InvocationHandler {
private static class ConnectionInvocationHandler implements InvocationHandler {
private final Connection target;

View File

@ -0,0 +1,110 @@
/*
* 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.testing.util.jpa;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import java.net.URL;
import java.util.List;
import java.util.Properties;
public class DelegatingPersistenceUnitInfo implements PersistenceUnitInfo {
private final PersistenceUnitInfo delegate;
public DelegatingPersistenceUnitInfo(PersistenceUnitInfo delegate) {
this.delegate = delegate;
}
@Override
public String getPersistenceUnitName() {
return delegate.getPersistenceUnitName();
}
@Override
public String getPersistenceProviderClassName() {
return delegate.getPersistenceProviderClassName();
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return delegate.getTransactionType();
}
@Override
public DataSource getJtaDataSource() {
return delegate.getJtaDataSource();
}
@Override
public DataSource getNonJtaDataSource() {
return delegate.getNonJtaDataSource();
}
@Override
public List<String> getMappingFileNames() {
return delegate.getMappingFileNames();
}
@Override
public List<URL> getJarFileUrls() {
return delegate.getJarFileUrls();
}
@Override
public URL getPersistenceUnitRootUrl() {
return delegate.getPersistenceUnitRootUrl();
}
@Override
public List<String> getManagedClassNames() {
return delegate.getManagedClassNames();
}
@Override
public boolean excludeUnlistedClasses() {
return delegate.excludeUnlistedClasses();
}
@Override
public SharedCacheMode getSharedCacheMode() {
return delegate.getSharedCacheMode();
}
@Override
public ValidationMode getValidationMode() {
return delegate.getValidationMode();
}
@Override
public Properties getProperties() {
return delegate.getProperties();
}
@Override
public String getPersistenceXMLSchemaVersion() {
return delegate.getPersistenceXMLSchemaVersion();
}
@Override
public ClassLoader getClassLoader() {
return delegate.getClassLoader();
}
@Override
public void addTransformer(ClassTransformer transformer) {
delegate.addTransformer( transformer );
}
@Override
public ClassLoader getNewTempClassLoader() {
return null;
}
}

View File

@ -0,0 +1,117 @@
/*
* 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.testing.util.jpa;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.hibernate.jpa.HibernatePersistenceProvider;
public class PersistenceUnitInfoAdapter implements PersistenceUnitInfo {
private final Properties properties;
public PersistenceUnitInfoAdapter() {
this( new Properties() );
}
public PersistenceUnitInfoAdapter(Properties properties) {
this.properties = properties;
}
@Override
public String getPersistenceUnitName() {
return "pu";
}
@Override
public String getPersistenceProviderClassName() {
return HibernatePersistenceProvider.class.getName();
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
@Override
public DataSource getJtaDataSource() {
return null;
}
@Override
public DataSource getNonJtaDataSource() {
return null;
}
@Override
public List<String> getMappingFileNames() {
return Collections.emptyList();
}
@Override
public List<URL> getJarFileUrls() {
return Collections.emptyList();
}
@Override
public URL getPersistenceUnitRootUrl() {
return null;
}
@Override
public List<String> getManagedClassNames() {
return Collections.emptyList();
}
@Override
public boolean excludeUnlistedClasses() {
return false;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return SharedCacheMode.NONE;
}
@Override
public ValidationMode getValidationMode() {
return ValidationMode.NONE;
}
@Override
public Properties getProperties() {
return properties;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return "2.1";
}
@Override
public ClassLoader getClassLoader() {
return PersistenceUnitInfoAdapter.class.getClassLoader();
}
@Override
public void addTransformer(ClassTransformer transformer) {
throw new UnsupportedOperationException();
}
@Override
public ClassLoader getNewTempClassLoader() {
return null;
}
}

View File

@ -0,0 +1,130 @@
/*
* 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
*/
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.testing.util.jpa;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import org.hibernate.jpa.HibernatePersistenceProvider;
/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
public class PersistenceUnitInfoPropertiesWrapper implements PersistenceUnitInfo {
private Properties properties;
public PersistenceUnitInfoPropertiesWrapper() {
}
public PersistenceUnitInfoPropertiesWrapper(Properties properties) {
this.properties = properties;
}
public String getPersistenceUnitName() {
return "persistenceUnitAdapter";
}
public String getPersistenceProviderClassName() {
return HibernatePersistenceProvider.class.getName();
}
public PersistenceUnitTransactionType getTransactionType() {
return null;
}
public DataSource getJtaDataSource() {
return null;
}
public DataSource getNonJtaDataSource() {
return null;
}
public List<String> getMappingFileNames() {
return Collections.emptyList();
}
public List<URL> getJarFileUrls() {
return Collections.emptyList();
}
public URL getPersistenceUnitRootUrl() {
return null;
}
public List<String> getManagedClassNames() {
return Collections.emptyList();
}
public boolean excludeUnlistedClasses() {
return false;
}
public SharedCacheMode getSharedCacheMode() {
return null;
}
public ValidationMode getValidationMode() {
return null;
}
public Properties getProperties() {
if ( properties == null ) {
properties = new Properties();
}
return properties;
}
public String getPersistenceXMLSchemaVersion() {
return null;
}
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
public void addTransformer(ClassTransformer transformer) {
}
public ClassLoader getNewTempClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
}

View File

@ -71,6 +71,10 @@ public class EnhancementHelper {
}
};
if ( options.getEnableExtendedEnhancement() ) {
project.getLogger().warn("Extended enhancement is enabled. Classes other than entities may be modified. You should consider access the entities using getter/setter methods and disable this property. Use at your own risk." );
}
final Enhancer enhancer = Environment.getBytecodeProvider().getEnhancer( enhancementContext );
for ( File classesDir: sourceSet.getOutput().getClassesDirs() ) {

View File

@ -6,36 +6,11 @@
*/
package org.hibernate.orm.tooling.gradle;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileTree;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
import org.gradle.api.tasks.SourceSet;
import org.hibernate.bytecode.enhance.spi.DefaultEnhancementContext;
import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.enhance.spi.Enhancer;
import org.hibernate.bytecode.enhance.spi.UnloadedClass;
import org.hibernate.bytecode.enhance.spi.UnloadedField;
import org.hibernate.cfg.Environment;
/**
* The Hibernate Gradle plugin. Adds Hibernate build-time capabilities into your Gradle-based build.
*
@ -44,8 +19,6 @@ import org.hibernate.cfg.Environment;
*/
@SuppressWarnings("serial")
public class HibernatePlugin implements Plugin<Project> {
private final Logger logger = Logging.getLogger( HibernatePlugin.class );
public void apply(Project project) {
project.getPlugins().apply( "java" );
@ -55,16 +28,12 @@ public class HibernatePlugin implements Plugin<Project> {
project.getExtensions().add( "hibernate", hibernateExtension );
project.afterEvaluate(
project1 -> {
if ( hibernateExtension.enhance != null ) {
applyEnhancement( project1, hibernateExtension );
}
}
p -> applyEnhancement( p, hibernateExtension )
);
}
private void applyEnhancement(final Project project, final HibernateExtension hibernateExtension) {
if ( !hibernateExtension.enhance.shouldApply() ) {
if ( hibernateExtension.enhance == null || ! hibernateExtension.enhance.shouldApply() ) {
project.getLogger().warn( "Skipping Hibernate bytecode enhancement since no feature is enabled" );
return;
}