Merge remote-tracking branch 'upstream5/master' into wip/6.0_merged_4
This commit is contained in:
commit
726dbeef34
12
README.md
12
README.md
|
@ -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"
|
||||
-------------------------------------------------------------
|
||||
|
|
|
@ -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)
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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[] {
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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 + ")";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 ) );
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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" ) );
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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!" );
|
||||
}
|
||||
}
|
|
@ -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() ) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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() ) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue