mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-18 00:55:16 +00:00
Merge branch 'main' into wip/6.0
This commit is contained in:
commit
98e64579fa
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
BIN
gradlew.bat
vendored
BIN
gradlew.bat
vendored
Binary file not shown.
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* 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.boot.model.naming;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Originally copied from Spring Boot as this strategy is popular there
|
||||||
|
* (original name is SpringPhysicalNamingStrategy).
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @author Madhura Bhave
|
||||||
|
*/
|
||||||
|
public class CamelCaseToUnderscoresNamingStrategy implements PhysicalNamingStrategy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||||
|
return apply( name, jdbcEnvironment );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||||
|
return apply( name, jdbcEnvironment );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||||
|
return apply( name, jdbcEnvironment );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||||
|
return apply( name, jdbcEnvironment );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
|
||||||
|
return apply( name, jdbcEnvironment );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Identifier apply(final Identifier name, final JdbcEnvironment jdbcEnvironment) {
|
||||||
|
if ( name == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuilder builder = new StringBuilder( name.getText().replace( '.', '_' ) );
|
||||||
|
for ( int i = 1; i < builder.length() - 1; i++ ) {
|
||||||
|
if ( isUnderscoreRequired( builder.charAt( i - 1 ), builder.charAt( i ), builder.charAt( i + 1 ) ) ) {
|
||||||
|
builder.insert( i++, '_' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getIdentifier( builder.toString(), name.isQuoted(), jdbcEnvironment );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an identifier for the specified details. By default this method will return an identifier
|
||||||
|
* with the name adapted based on the result of {@link #isCaseInsensitive(JdbcEnvironment)}
|
||||||
|
*
|
||||||
|
* @param name the name of the identifier
|
||||||
|
* @param quoted if the identifier is quoted
|
||||||
|
* @param jdbcEnvironment the JDBC environment
|
||||||
|
*
|
||||||
|
* @return an identifier instance
|
||||||
|
*/
|
||||||
|
protected Identifier getIdentifier(String name, final boolean quoted, final JdbcEnvironment jdbcEnvironment) {
|
||||||
|
if ( isCaseInsensitive( jdbcEnvironment ) ) {
|
||||||
|
name = name.toLowerCase( Locale.ROOT );
|
||||||
|
}
|
||||||
|
return new Identifier( name, quoted );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify whether the database is case sensitive.
|
||||||
|
*
|
||||||
|
* @param jdbcEnvironment the JDBC environment which can be used to determine case
|
||||||
|
*
|
||||||
|
* @return true if the database is case insensitive sensitivity
|
||||||
|
*/
|
||||||
|
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUnderscoreRequired(final char before, final char current, final char after) {
|
||||||
|
return Character.isLowerCase( before ) && Character.isUpperCase( current ) && Character.isLowerCase( after );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -630,7 +630,7 @@ public void reassociateProxy(Object value, Object id) throws MappingException {
|
|||||||
private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) {
|
private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) {
|
||||||
if ( li.getSession() != this.getSession() ) {
|
if ( li.getSession() != this.getSession() ) {
|
||||||
final EntityPersister persister = session.getFactory().getMetamodel().entityPersister( li.getEntityName() );
|
final EntityPersister persister = session.getFactory().getMetamodel().entityPersister( li.getEntityName() );
|
||||||
final EntityKey key = session.generateEntityKey( li.getIdentifier(), persister );
|
final EntityKey key = session.generateEntityKey( li.getInternalIdentifier(), persister );
|
||||||
// any earlier proxy takes precedence
|
// any earlier proxy takes precedence
|
||||||
getOrInitializeProxiesByKey().putIfAbsent( key, proxy );
|
getOrInitializeProxiesByKey().putIfAbsent( key, proxy );
|
||||||
proxy.getHibernateLazyInitializer().setSession( session );
|
proxy.getHibernateLazyInitializer().setSession( session );
|
||||||
@ -1338,7 +1338,7 @@ && isFoundInParent( propertyName, childEntity, persister, collectionPersister, p
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ( found ) {
|
if ( found ) {
|
||||||
return proxy.getHibernateLazyInitializer().getIdentifier();
|
return proxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public void onEvict(EvictEvent event) throws HibernateException {
|
|||||||
|
|
||||||
if ( object instanceof HibernateProxy ) {
|
if ( object instanceof HibernateProxy ) {
|
||||||
final LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
final LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
|
||||||
final Object id = li.getIdentifier();
|
final Object id = li.getInternalIdentifier();
|
||||||
if ( id == null ) {
|
if ( id == null ) {
|
||||||
throw new IllegalArgumentException( "Could not determine identifier of proxy passed to evict()" );
|
throw new IllegalArgumentException( "Could not determine identifier of proxy passed to evict()" );
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateExcepti
|
|||||||
LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
|
LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
|
||||||
if ( li.isUninitialized() ) {
|
if ( li.isUninitialized() ) {
|
||||||
LOG.trace( "Ignoring uninitialized proxy" );
|
LOG.trace( "Ignoring uninitialized proxy" );
|
||||||
event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) );
|
event.setResult( source.load( li.getEntityName(), li.getInternalIdentifier() ) );
|
||||||
//EARLY EXIT!
|
//EARLY EXIT!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1471,7 +1471,7 @@ public Object getIdentifier(Object object) throws HibernateException {
|
|||||||
if ( li.getSession() != this ) {
|
if ( li.getSession() != this ) {
|
||||||
throw new TransientObjectException( "The proxy was not associated with this session" );
|
throw new TransientObjectException( "The proxy was not associated with this session" );
|
||||||
}
|
}
|
||||||
return li.getIdentifier();
|
return li.getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EntityEntry entry = persistenceContext.getEntry( object );
|
EntityEntry entry = persistenceContext.getEntry( object );
|
||||||
@ -1499,7 +1499,7 @@ public Object getContextEntityIdentifier(Object object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object getProxyIdentifier(Object proxy) {
|
private Object getProxyIdentifier(Object proxy) {
|
||||||
return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getIdentifier();
|
return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -68,7 +68,7 @@ public Object getIdentifier(Object entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( entity instanceof HibernateProxy ) {
|
if ( entity instanceof HibernateProxy ) {
|
||||||
return ((HibernateProxy) entity).getHibernateLazyInitializer().getIdentifier();
|
return ((HibernateProxy) entity).getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else if ( entity instanceof ManagedEntity ) {
|
else if ( entity instanceof ManagedEntity ) {
|
||||||
EntityEntry entityEntry = ((ManagedEntity) entity).$$_hibernate_getEntityEntry();
|
EntityEntry entityEntry = ((ManagedEntity) entity).$$_hibernate_getEntityEntry();
|
||||||
|
@ -122,8 +122,8 @@ public String getAlias(Dialect dialect) {
|
|||||||
if ( lastLetter == -1 ) {
|
if ( lastLetter == -1 ) {
|
||||||
alias = "column";
|
alias = "column";
|
||||||
}
|
}
|
||||||
else if ( name.length() > lastLetter + 1 ) {
|
else if ( alias.length() > lastLetter + 1 ) {
|
||||||
alias = name.substring( 0, lastLetter + 1 );
|
alias = alias.substring( 0, lastLetter + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean useRawName = name.length() + suffix.length() <= dialect.getMaxAliasLength()
|
boolean useRawName = name.length() + suffix.length() <= dialect.getMaxAliasLength()
|
||||||
|
@ -81,6 +81,11 @@ public final String getEntityName() {
|
|||||||
return entityName;
|
return entityName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Object getInternalIdentifier() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Object getIdentifier() {
|
public final Object getIdentifier() {
|
||||||
if ( isUninitialized() && isInitializeProxyWhenAccessingIdentifier() ) {
|
if ( isUninitialized() && isInitializeProxyWhenAccessingIdentifier() ) {
|
||||||
@ -90,7 +95,7 @@ public final Object getIdentifier() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInitializeProxyWhenAccessingIdentifier() {
|
private boolean isInitializeProxyWhenAccessingIdentifier() {
|
||||||
return session != null && session.getFactory()
|
return getSession() != null && getSession().getFactory()
|
||||||
.getSessionFactoryOptions()
|
.getSessionFactoryOptions()
|
||||||
.getJpaCompliance().isJpaProxyComplianceEnabled();
|
.getJpaCompliance().isJpaProxyComplianceEnabled();
|
||||||
}
|
}
|
||||||
@ -256,7 +261,7 @@ else if ( session.isOpenOrWaitingForAutoClose() && session.isConnected() ) {
|
|||||||
public final void initializeWithoutLoadIfPossible() {
|
public final void initializeWithoutLoadIfPossible() {
|
||||||
if ( !initialized && session != null && session.isOpenOrWaitingForAutoClose() ) {
|
if ( !initialized && session != null && session.isOpenOrWaitingForAutoClose() ) {
|
||||||
final EntityKey key = session.generateEntityKey(
|
final EntityKey key = session.generateEntityKey(
|
||||||
getIdentifier(),
|
getInternalIdentifier(),
|
||||||
session.getFactory().getMetamodel().entityPersister( getEntityName() )
|
session.getFactory().getMetamodel().entityPersister( getEntityName() )
|
||||||
);
|
);
|
||||||
final Object entity = session.getPersistenceContextInternal().getEntity( key );
|
final Object entity = session.getPersistenceContextInternal().getEntity( key );
|
||||||
@ -301,7 +306,7 @@ protected final boolean isConnectedToSession() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object getProxyOrNull() {
|
private Object getProxyOrNull() {
|
||||||
final EntityKey entityKey = generateEntityKeyOrNull( getIdentifier(), session, getEntityName() );
|
final EntityKey entityKey = generateEntityKeyOrNull( getInternalIdentifier(), session, getEntityName() );
|
||||||
if ( entityKey != null && session != null && session.isOpenOrWaitingForAutoClose() ) {
|
if ( entityKey != null && session != null && session.isOpenOrWaitingForAutoClose() ) {
|
||||||
return session.getPersistenceContextInternal().getProxy( entityKey );
|
return session.getPersistenceContextInternal().getProxy( entityKey );
|
||||||
}
|
}
|
||||||
@ -322,7 +327,7 @@ public final void setImplementation(Object target) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Object getImplementation(SharedSessionContractImplementor s) throws HibernateException {
|
public final Object getImplementation(SharedSessionContractImplementor s) throws HibernateException {
|
||||||
final EntityKey entityKey = generateEntityKeyOrNull( getIdentifier(), s, getEntityName() );
|
final EntityKey entityKey = generateEntityKeyOrNull( getInternalIdentifier(), s, getEntityName() );
|
||||||
return ( entityKey == null ? null : s.getPersistenceContext().getEntity( entityKey ) );
|
return ( entityKey == null ? null : s.getPersistenceContext().getEntity( entityKey ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +377,7 @@ public final void setReadOnly(boolean readOnly) {
|
|||||||
}
|
}
|
||||||
this.readOnly = readOnly;
|
this.readOnly = readOnly;
|
||||||
if ( initialized ) {
|
if ( initialized ) {
|
||||||
EntityKey key = generateEntityKeyOrNull( getIdentifier(), session, getEntityName() );
|
EntityKey key = generateEntityKeyOrNull( getInternalIdentifier(), session, getEntityName() );
|
||||||
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
final PersistenceContext persistenceContext = session.getPersistenceContext();
|
||||||
if ( key != null && persistenceContext.containsEntity( key ) ) {
|
if ( key != null && persistenceContext.containsEntity( key ) ) {
|
||||||
persistenceContext.setReadOnly( target, readOnly );
|
persistenceContext.setReadOnly( target, readOnly );
|
||||||
|
@ -28,6 +28,17 @@ public interface LazyInitializer {
|
|||||||
*
|
*
|
||||||
* @return The identifier value.
|
* @return The identifier value.
|
||||||
*/
|
*/
|
||||||
|
default Object getInternalIdentifier() {
|
||||||
|
return getIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the identifier value for the entity our owning proxy represents.
|
||||||
|
*
|
||||||
|
* When JPA proxy compliance is enabled the proxy is initialized.
|
||||||
|
*
|
||||||
|
* @return The identifier value.
|
||||||
|
*/
|
||||||
Object getIdentifier();
|
Object getIdentifier();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,7 +116,7 @@ public Object writeReplace() {
|
|||||||
private Object serializableProxy() {
|
private Object serializableProxy() {
|
||||||
return new SerializableMapProxy(
|
return new SerializableMapProxy(
|
||||||
li.getEntityName(),
|
li.getEntityName(),
|
||||||
li.getIdentifier(),
|
li.getInternalIdentifier(),
|
||||||
( li.isReadOnlySettingAvailable() ? Boolean.valueOf( li.isReadOnly() ) : li.isReadOnlyBeforeAttachedToSession() ),
|
( li.isReadOnlySettingAvailable() ? Boolean.valueOf( li.isReadOnly() ) : li.isReadOnlyBeforeAttachedToSession() ),
|
||||||
li.getSessionFactoryUuid(),
|
li.getSessionFactoryUuid(),
|
||||||
li.isAllowLoadOutsideTransaction()
|
li.isAllowLoadOutsideTransaction()
|
||||||
|
@ -84,7 +84,7 @@ protected Object serializableProxy() {
|
|||||||
getEntityName(),
|
getEntityName(),
|
||||||
persistentClass,
|
persistentClass,
|
||||||
interfaces,
|
interfaces,
|
||||||
getIdentifier(),
|
getInternalIdentifier(),
|
||||||
( isReadOnlySettingAvailable() ? Boolean.valueOf( isReadOnly() ) : isReadOnlyBeforeAttachedToSession() ),
|
( isReadOnlySettingAvailable() ? Boolean.valueOf( isReadOnly() ) : isReadOnlyBeforeAttachedToSession() ),
|
||||||
getSessionFactoryUuid(),
|
getSessionFactoryUuid(),
|
||||||
isAllowLoadOutsideTransaction(),
|
isAllowLoadOutsideTransaction(),
|
||||||
|
@ -214,7 +214,7 @@ public Object getIdentifier(Object entity, SharedSessionContractImplementor sess
|
|||||||
id = entity;
|
id = entity;
|
||||||
}
|
}
|
||||||
else if ( HibernateProxy.class.isInstance( entity ) ) {
|
else if ( HibernateProxy.class.isInstance( entity ) ) {
|
||||||
id = ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
id = ( (HibernateProxy) entity ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( idGetter == null ) {
|
if ( idGetter == null ) {
|
||||||
@ -451,7 +451,7 @@ private static Object determineEntityId(
|
|||||||
|
|
||||||
if ( entity instanceof HibernateProxy ) {
|
if ( entity instanceof HibernateProxy ) {
|
||||||
// entity is a proxy, so we know it is not transient; just return ID from proxy
|
// entity is a proxy, so we know it is not transient; just return ID from proxy
|
||||||
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
|
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( session != null ) {
|
if ( session != null ) {
|
||||||
|
@ -335,7 +335,7 @@ public int getHashCode(Object x, SessionFactoryImplementor factory) {
|
|||||||
|
|
||||||
final Object id;
|
final Object id;
|
||||||
if ( x instanceof HibernateProxy ) {
|
if ( x instanceof HibernateProxy ) {
|
||||||
id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getIdentifier();
|
id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final Class mappedClass = persister.getMappedClass();
|
final Class mappedClass = persister.getMappedClass();
|
||||||
@ -365,7 +365,7 @@ public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) {
|
|||||||
Object xid;
|
Object xid;
|
||||||
if ( x instanceof HibernateProxy ) {
|
if ( x instanceof HibernateProxy ) {
|
||||||
xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
|
xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
|
||||||
.getIdentifier();
|
.getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( mappedClass.isAssignableFrom( x.getClass() ) ) {
|
if ( mappedClass.isAssignableFrom( x.getClass() ) ) {
|
||||||
@ -379,7 +379,8 @@ public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) {
|
|||||||
|
|
||||||
Object yid;
|
Object yid;
|
||||||
if ( y instanceof HibernateProxy ) {
|
if ( y instanceof HibernateProxy ) {
|
||||||
yid = ( (HibernateProxy) y ).getHibernateLazyInitializer().getIdentifier();
|
yid = ( (HibernateProxy) y ).getHibernateLazyInitializer()
|
||||||
|
.getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( mappedClass.isAssignableFrom( y.getClass() ) ) {
|
if ( mappedClass.isAssignableFrom( y.getClass() ) ) {
|
||||||
@ -523,7 +524,7 @@ public String toLoggableString(Object value, SessionFactoryImplementor factory)
|
|||||||
final Object id;
|
final Object id;
|
||||||
if ( value instanceof HibernateProxy ) {
|
if ( value instanceof HibernateProxy ) {
|
||||||
HibernateProxy proxy = (HibernateProxy) value;
|
HibernateProxy proxy = (HibernateProxy) value;
|
||||||
id = proxy.getHibernateLazyInitializer().getIdentifier();
|
id = proxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
id = persister.getIdentifier( value );
|
id = persister.getIdentifier( value );
|
||||||
|
@ -0,0 +1,211 @@
|
|||||||
|
package org.hibernate.jpa.test.ops;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.EmbeddedId;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil2.fromTransaction;
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil2.inTransaction;
|
||||||
|
|
||||||
|
@TestForIssue( jiraKey = "HHH-14608")
|
||||||
|
public class MergeJpaComplianceTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] {
|
||||||
|
Person.class, Occupation.class, PersonOccupation.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addConfigOptions(Map config) {
|
||||||
|
config.put( org.hibernate.cfg.AvailableSettings.JPA_PROXY_COMPLIANCE, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMerge() {
|
||||||
|
Person person = fromTransaction(
|
||||||
|
entityManagerFactory(),
|
||||||
|
entityManager -> {
|
||||||
|
Person p;
|
||||||
|
p = new Person( "1", "Fab" );
|
||||||
|
Occupation t = new Occupation( 1l, "Some work" );
|
||||||
|
|
||||||
|
entityManager.persist( p );
|
||||||
|
entityManager.persist( t );
|
||||||
|
|
||||||
|
entityManager.flush();
|
||||||
|
|
||||||
|
PersonOccupation participant = new PersonOccupation( p, t );
|
||||||
|
entityManager.persist( participant );
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
inTransaction(
|
||||||
|
entityManagerFactory(),
|
||||||
|
entityManager -> {
|
||||||
|
person.setName( "Fabiana" );
|
||||||
|
entityManager.merge( person );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Person")
|
||||||
|
public static class Person {
|
||||||
|
@Id
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "pk.person", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
private List<PersonOccupation> occupations;
|
||||||
|
|
||||||
|
public Person() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person(String id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PersonOccupation> getOccupations() {
|
||||||
|
return occupations;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addOccupationPeoplet(PersonOccupation personOccupation) {
|
||||||
|
if ( this.occupations == null ) {
|
||||||
|
occupations = new ArrayList<>();
|
||||||
|
}
|
||||||
|
this.occupations.add( personOccupation );
|
||||||
|
personOccupation.getPk().setPerson( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setOccupations(List<PersonOccupation> occupations) {
|
||||||
|
this.occupations = occupations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Occupation")
|
||||||
|
public static class Occupation {
|
||||||
|
@Id
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "pk.occupation", cascade = CascadeType.ALL)
|
||||||
|
private List<PersonOccupation> personOccupations;
|
||||||
|
|
||||||
|
protected Occupation() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Occupation(long id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PersonOccupation> getPersonOccupations() {
|
||||||
|
return personOccupations;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addPersonOccupation(PersonOccupation participant) {
|
||||||
|
if ( personOccupations == null ) {
|
||||||
|
personOccupations = new ArrayList<>();
|
||||||
|
}
|
||||||
|
personOccupations.add( participant );
|
||||||
|
participant.getPk().setOccupation( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPersonOccupations(List<PersonOccupation> personOccupations) {
|
||||||
|
this.personOccupations = personOccupations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "PersonOccupation")
|
||||||
|
public static class PersonOccupation {
|
||||||
|
@EmbeddedId
|
||||||
|
private PersonOccupationPK pk = new PersonOccupationPK();
|
||||||
|
|
||||||
|
protected PersonOccupation() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersonOccupation(Person person, Occupation occupation) {
|
||||||
|
person.addOccupationPeoplet( this );
|
||||||
|
occupation.addPersonOccupation( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersonOccupationPK getPk() {
|
||||||
|
return pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPk(PersonOccupationPK pk) {
|
||||||
|
this.pk = pk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class PersonOccupationPK implements Serializable {
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
private Person person;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
private Occupation occupation;
|
||||||
|
|
||||||
|
public Person getPerson() {
|
||||||
|
return person;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPerson(Person person) {
|
||||||
|
this.person = person;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Occupation getOccupation() {
|
||||||
|
return occupation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOccupation(Occupation occupation) {
|
||||||
|
this.occupation = occupation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.hibernate.orm.test.mapping.lazytoone.collectioninitializer;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Company {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Company{" +
|
||||||
|
"id=" + id +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.hibernate.orm.test.mapping.lazytoone.collectioninitializer;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class CostCenter {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false)
|
||||||
|
private Company company;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CostCenter{" +
|
||||||
|
"id=" + id +
|
||||||
|
", company=" + company +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Company getCompany() {
|
||||||
|
return company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompany(Company company) {
|
||||||
|
this.company = company;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* 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.mapping.lazytoone.collectioninitializer;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.hibernate.loader.BatchFetchStyle.PADDED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test lazy-to-one initialization within a collection initialization,
|
||||||
|
* with the PADDED batch-fetch-style.
|
||||||
|
* <p>
|
||||||
|
* In particular, with Offer having a lazy to-one association to CostCenter,
|
||||||
|
* and User having a lazy to-many association to UserAuthorization1 and UserAuthorization2,
|
||||||
|
* and UserAuthorization1 and UserAuthorization2 having an EAGER association to CostCenter,
|
||||||
|
* test:
|
||||||
|
* <ul>
|
||||||
|
* <li>Get a reference to Offer (which will create an uninitialized proxy for CostCenter)</li>
|
||||||
|
* <li>Get a reference to User</li>
|
||||||
|
* <li>Initialize User's collection containing UserAuthorization1 and UserAuthorization2,
|
||||||
|
* which will initialize CostCenter DURING the loading,
|
||||||
|
* which used to fail because we tried to initialize CostCenter twice
|
||||||
|
* (once for UserAuthorization1, and once for UserAuthorization2)</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@RunWith(BytecodeEnhancerRunner.class)
|
||||||
|
@TestForIssue(jiraKey = "HHH-14730")
|
||||||
|
public class InitLazyToOneWithinPaddedCollectionInitializationAllowProxyTest
|
||||||
|
extends BaseNonConfigCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applyMetadataSources(MetadataSources sources) {
|
||||||
|
super.applyMetadataSources( sources );
|
||||||
|
sources.addAnnotatedClass( User.class );
|
||||||
|
sources.addAnnotatedClass( UserAuthorization.class );
|
||||||
|
sources.addAnnotatedClass( Company.class );
|
||||||
|
sources.addAnnotatedClass( CostCenter.class );
|
||||||
|
sources.addAnnotatedClass( Offer.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) {
|
||||||
|
super.configureStandardServiceRegistryBuilder( ssrb );
|
||||||
|
ssrb.applySetting( AvailableSettings.ALLOW_ENHANCEMENT_AS_PROXY, true );
|
||||||
|
ssrb.applySetting( AvailableSettings.BATCH_FETCH_STYLE, PADDED );
|
||||||
|
ssrb.applySetting( AvailableSettings.DEFAULT_BATCH_FETCH_SIZE, 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterSessionFactoryBuilt(SessionFactoryImplementor sessionFactory) {
|
||||||
|
inTransaction( session -> {
|
||||||
|
User user0 = new User();
|
||||||
|
user0.setId( 0L );
|
||||||
|
session.persist( user0 );
|
||||||
|
|
||||||
|
User user1 = new User();
|
||||||
|
user1.setId( 1L );
|
||||||
|
session.persist( user1 );
|
||||||
|
|
||||||
|
User user2 = new User();
|
||||||
|
user2.setId( 2L );
|
||||||
|
session.persist( user2 );
|
||||||
|
|
||||||
|
Company company = new Company();
|
||||||
|
company.setId( 2L );
|
||||||
|
session.persist( company );
|
||||||
|
|
||||||
|
CostCenter costCenter = new CostCenter();
|
||||||
|
costCenter.setId( 3L );
|
||||||
|
costCenter.setCompany( company );
|
||||||
|
session.persist( costCenter );
|
||||||
|
|
||||||
|
UserAuthorization user0Authorization1 = new UserAuthorization();
|
||||||
|
user0Authorization1.setId( 1L );
|
||||||
|
user0Authorization1.setUser( user0 );
|
||||||
|
user0Authorization1.setCostCenter( costCenter );
|
||||||
|
session.persist( user0Authorization1 );
|
||||||
|
|
||||||
|
UserAuthorization user1Authorization1 = new UserAuthorization();
|
||||||
|
user1Authorization1.setId( 11L );
|
||||||
|
user1Authorization1.setUser( user1 );
|
||||||
|
user1Authorization1.setCostCenter( costCenter );
|
||||||
|
session.persist( user1Authorization1 );
|
||||||
|
|
||||||
|
UserAuthorization user1Authorization2 = new UserAuthorization();
|
||||||
|
user1Authorization2.setId( 12L );
|
||||||
|
user1Authorization2.setUser( user1 );
|
||||||
|
user1Authorization2.setCostCenter( costCenter );
|
||||||
|
session.persist( user1Authorization2 );
|
||||||
|
|
||||||
|
UserAuthorization user2Authorization1 = new UserAuthorization();
|
||||||
|
user2Authorization1.setId( 21L );
|
||||||
|
user2Authorization1.setUser( user2 );
|
||||||
|
user2Authorization1.setCostCenter( costCenter );
|
||||||
|
session.persist( user2Authorization1 );
|
||||||
|
|
||||||
|
UserAuthorization user2Authorization2 = new UserAuthorization();
|
||||||
|
user2Authorization2.setId( 22L );
|
||||||
|
user2Authorization2.setUser( user2 );
|
||||||
|
user2Authorization2.setCostCenter( costCenter );
|
||||||
|
session.persist( user2Authorization2 );
|
||||||
|
|
||||||
|
UserAuthorization user2Authorization3 = new UserAuthorization();
|
||||||
|
user2Authorization3.setId( 23L );
|
||||||
|
user2Authorization3.setUser( user2 );
|
||||||
|
user2Authorization3.setCostCenter( costCenter );
|
||||||
|
session.persist( user2Authorization3 );
|
||||||
|
|
||||||
|
Offer offer = new Offer();
|
||||||
|
offer.setId( 6L );
|
||||||
|
offer.setCostCenter( costCenter );
|
||||||
|
session.persist( offer );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOneReference() {
|
||||||
|
inTransaction( (session) -> {
|
||||||
|
// Add a lazy proxy of the cost center to the persistence context
|
||||||
|
// through the lazy to-one association from the offer.
|
||||||
|
Offer offer = session.find( Offer.class, 6L );
|
||||||
|
|
||||||
|
User user = session.find( User.class, 0L );
|
||||||
|
|
||||||
|
assertThat( Hibernate.isInitialized( offer.getCostCenter() ) ).isFalse();
|
||||||
|
|
||||||
|
// Trigger lazy-loading of the cost center
|
||||||
|
// through the loading of the authorization,
|
||||||
|
// which contains an eager reference to the cost center.
|
||||||
|
assertThat( user.getAuthorizations().size() ).isEqualTo( 1 );
|
||||||
|
|
||||||
|
assertThat( Hibernate.isInitialized( offer.getCostCenter() ) ).isTrue();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTwoReferences() {
|
||||||
|
inTransaction( (session) -> {
|
||||||
|
// Add a lazy proxy of the cost center to the persistence context
|
||||||
|
// through the lazy to-one association from the offer.
|
||||||
|
Offer offer = session.find( Offer.class, 6L );
|
||||||
|
|
||||||
|
User user = session.find( User.class, 1L );
|
||||||
|
|
||||||
|
assertThat( Hibernate.isInitialized( offer.getCostCenter() ) ).isFalse();
|
||||||
|
|
||||||
|
// Trigger lazy-loading of the cost center
|
||||||
|
// through the loading of the 2 authorizations,
|
||||||
|
// which both contain an eager reference to the cost center.
|
||||||
|
assertThat( user.getAuthorizations().size() ).isEqualTo( 2 );
|
||||||
|
|
||||||
|
assertThat( Hibernate.isInitialized( offer.getCostCenter() ) ).isTrue();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThreeReferences() {
|
||||||
|
inTransaction( (session) -> {
|
||||||
|
// Add a lazy proxy of the cost center to the persistence context
|
||||||
|
// through the lazy to-one association from the offer.
|
||||||
|
Offer offer = session.find( Offer.class, 6L );
|
||||||
|
|
||||||
|
User user = session.find( User.class, 2L );
|
||||||
|
|
||||||
|
assertThat( Hibernate.isInitialized( offer.getCostCenter() ) ).isFalse();
|
||||||
|
|
||||||
|
// Trigger lazy-loading of the cost center
|
||||||
|
// through the loading of the 3 authorizations,
|
||||||
|
// which all contain an eager reference to the cost center.
|
||||||
|
assertThat( user.getAuthorizations().size() ).isEqualTo( 3 );
|
||||||
|
|
||||||
|
assertThat( Hibernate.isInitialized( offer.getCostCenter() ) ).isTrue();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.hibernate.orm.test.mapping.lazytoone.collectioninitializer;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
import static javax.persistence.FetchType.LAZY;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Offer {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = LAZY, optional = false)
|
||||||
|
private CostCenter costCenter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Offer{" +
|
||||||
|
"id=" + getId() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CostCenter getCostCenter() {
|
||||||
|
return costCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCostCenter(CostCenter costCenter) {
|
||||||
|
this.costCenter = costCenter;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package org.hibernate.orm.test.mapping.lazytoone.collectioninitializer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import static javax.persistence.CascadeType.ALL;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "users")
|
||||||
|
public class User {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "user", cascade = ALL, orphanRemoval = true)
|
||||||
|
private List<UserAuthorization> authorizations = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User{" +
|
||||||
|
"id='" + getId() + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UserAuthorization> getAuthorizations() {
|
||||||
|
return authorizations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthorizations(List<UserAuthorization> authorizations) {
|
||||||
|
this.authorizations = authorizations;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package org.hibernate.orm.test.mapping.lazytoone.collectioninitializer;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class UserAuthorization {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false)
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false)
|
||||||
|
private CostCenter costCenter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "UserAuthorization{" +
|
||||||
|
"id='" + getId() + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CostCenter getCostCenter() {
|
||||||
|
return costCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCostCenter(CostCenter costCenter) {
|
||||||
|
this.costCenter = costCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.mapping;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.PostgreSQL94Dialect;
|
||||||
|
import org.hibernate.mapping.Column;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aliases should always be lower-case. This tests that an alias for
|
||||||
|
* a column name that ends in a character that is not a letter gets
|
||||||
|
* generated to be all in lower-case.
|
||||||
|
*
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class ColumnLastIndexNotLetterAliasTest {
|
||||||
|
// Arbitrarily choose PostgreSQL
|
||||||
|
private static final Dialect DIALECT = new PostgreSQL94Dialect();;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14720")
|
||||||
|
public void testColumnNameEndinWithNonCharacter() {
|
||||||
|
test( "aColumn1" );
|
||||||
|
test( "aColumn_" );
|
||||||
|
test( "aVeryVeryVeryLongColumnName1" );
|
||||||
|
test( "aVeryVeryVeryLongColumnName_" );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void test(String columnName) {
|
||||||
|
final Column column = new Column( columnName );
|
||||||
|
final String alias = column.getAlias( DIALECT );
|
||||||
|
assertEquals( alias.toLowerCase( Locale.ROOT ), alias );
|
||||||
|
}
|
||||||
|
}
|
@ -94,7 +94,7 @@ private void addCollectionChangeWorkUnit(
|
|||||||
|
|
||||||
if ( value instanceof HibernateProxy ) {
|
if ( value instanceof HibernateProxy ) {
|
||||||
final HibernateProxy hibernateProxy = (HibernateProxy) value;
|
final HibernateProxy hibernateProxy = (HibernateProxy) value;
|
||||||
id = hibernateProxy.getHibernateLazyInitializer().getIdentifier();
|
id = hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
// We've got to initialize the object from the proxy to later read its state.
|
// We've got to initialize the object from the proxy to later read its state.
|
||||||
value = EntityTools.getTargetFromProxy( session.getFactory(), hibernateProxy );
|
value = EntityTools.getTargetFromProxy( session.getFactory(), hibernateProxy );
|
||||||
// HHH-7249
|
// HHH-7249
|
||||||
|
@ -111,7 +111,7 @@ private void replaceNonAuditIdProxies(Map versionsEntity, Number revision) {
|
|||||||
final HibernateProxy hibernateProxy = (HibernateProxy) value;
|
final HibernateProxy hibernateProxy = (HibernateProxy) value;
|
||||||
final LazyInitializer initializer = hibernateProxy.getHibernateLazyInitializer();
|
final LazyInitializer initializer = hibernateProxy.getHibernateLazyInitializer();
|
||||||
final String entityName = initializer.getEntityName();
|
final String entityName = initializer.getEntityName();
|
||||||
final Object entityId = initializer.getIdentifier();
|
final Object entityId = initializer.getInternalIdentifier();
|
||||||
if ( enversService.getEntitiesConfigurations().isVersioned( entityName ) ) {
|
if ( enversService.getEntitiesConfigurations().isVersioned( entityName ) ) {
|
||||||
final String entityClassName = enversService.getEntitiesConfigurations().get( entityName ).getEntityClassName();
|
final String entityClassName = enversService.getEntitiesConfigurations().get( entityName ).getEntityClassName();
|
||||||
final Class entityClass = ReflectionTools.loadClass(
|
final Class entityClass = ReflectionTools.loadClass(
|
||||||
|
@ -88,7 +88,7 @@ public Object mapToIdFromEntity(final Object data) {
|
|||||||
|
|
||||||
if ( data instanceof HibernateProxy ) {
|
if ( data instanceof HibernateProxy ) {
|
||||||
final HibernateProxy hibernateProxy = (HibernateProxy) data;
|
final HibernateProxy hibernateProxy = (HibernateProxy) data;
|
||||||
return hibernateProxy.getHibernateLazyInitializer().getIdentifier();
|
return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return AccessController.doPrivileged(
|
return AccessController.doPrivileged(
|
||||||
@ -122,7 +122,7 @@ public void mapToMapFromEntity(Map<String, Object> data, final Object obj) {
|
|||||||
else {
|
else {
|
||||||
if ( obj instanceof HibernateProxy ) {
|
if ( obj instanceof HibernateProxy ) {
|
||||||
final HibernateProxy hibernateProxy = (HibernateProxy) obj;
|
final HibernateProxy hibernateProxy = (HibernateProxy) obj;
|
||||||
data.put( propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getIdentifier() );
|
data.put( propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final Object value = AccessController.doPrivileged(
|
final Object value = AccessController.doPrivileged(
|
||||||
|
@ -155,7 +155,7 @@ public void mapToMapFromEntity(Map<String, Object> data, Object obj) {
|
|||||||
else {
|
else {
|
||||||
if ( obj instanceof HibernateProxy ) {
|
if ( obj instanceof HibernateProxy ) {
|
||||||
final HibernateProxy proxy = (HibernateProxy) obj;
|
final HibernateProxy proxy = (HibernateProxy) obj;
|
||||||
data.put( propertyData.getName(), proxy.getHibernateLazyInitializer().getIdentifier() );
|
data.put( propertyData.getName(), proxy.getHibernateLazyInitializer().getInternalIdentifier() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final Object value = AccessController.doPrivileged(
|
final Object value = AccessController.doPrivileged(
|
||||||
|
@ -33,7 +33,7 @@ public static Object getIdentifier(SessionImplementor session, String entityName
|
|||||||
|
|
||||||
if ( obj instanceof HibernateProxy ) {
|
if ( obj instanceof HibernateProxy ) {
|
||||||
final HibernateProxy hibernateProxy = (HibernateProxy) obj;
|
final HibernateProxy hibernateProxy = (HibernateProxy) obj;
|
||||||
return hibernateProxy.getHibernateLazyInitializer().getIdentifier();
|
return hibernateProxy.getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
return session.getEntityPersister( entityName, obj ).getIdentifier( obj, session );
|
return session.getEntityPersister( entityName, obj ).getIdentifier( obj, session );
|
||||||
@ -51,7 +51,7 @@ public static Object getTargetFromProxy(SessionFactoryImplementor sessionFactory
|
|||||||
try {
|
try {
|
||||||
return tempSession.get(
|
return tempSession.get(
|
||||||
proxy.getHibernateLazyInitializer().getEntityName(),
|
proxy.getHibernateLazyInitializer().getEntityName(),
|
||||||
proxy.getHibernateLazyInitializer().getIdentifier()
|
proxy.getHibernateLazyInitializer().getInternalIdentifier()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -80,7 +80,7 @@ private Number getRevisionNumber(Map versionsEntity) {
|
|||||||
Object revisionInfoObject = ( (Map) versionsEntity.get( originalId ) ).get( revisionPropertyName );
|
Object revisionInfoObject = ( (Map) versionsEntity.get( originalId ) ).get( revisionPropertyName );
|
||||||
|
|
||||||
if ( revisionInfoObject instanceof HibernateProxy ) {
|
if ( revisionInfoObject instanceof HibernateProxy ) {
|
||||||
return (Number) ( (HibernateProxy) revisionInfoObject ).getHibernateLazyInitializer().getIdentifier();
|
return (Number) ( (HibernateProxy) revisionInfoObject ).getHibernateLazyInitializer().getInternalIdentifier();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Not a proxy - must be read from cache or with a join
|
// Not a proxy - must be read from cache or with a join
|
||||||
|
@ -114,8 +114,8 @@ public void testProxyIdentifier() {
|
|||||||
LazyInitializer lazyInitializer = proxyCreateByEnvers.getHibernateLazyInitializer();
|
LazyInitializer lazyInitializer = proxyCreateByEnvers.getHibernateLazyInitializer();
|
||||||
|
|
||||||
Assert.assertTrue( lazyInitializer.isUninitialized() );
|
Assert.assertTrue( lazyInitializer.isUninitialized() );
|
||||||
Assert.assertNotNull( lazyInitializer.getIdentifier() );
|
Assert.assertNotNull( lazyInitializer.getInternalIdentifier() );
|
||||||
Assert.assertEquals( tnae1.getId(), lazyInitializer.getIdentifier() );
|
Assert.assertEquals( tnae1.getId(), lazyInitializer.getInternalIdentifier() );
|
||||||
Assert.assertTrue( lazyInitializer.isUninitialized() );
|
Assert.assertTrue( lazyInitializer.isUninitialized() );
|
||||||
|
|
||||||
Assert.assertEquals( uste1.getId(), rev1.getReference().getId() );
|
Assert.assertEquals( uste1.getId(), rev1.getReference().getId() );
|
||||||
|
@ -9,34 +9,10 @@ description = 'Integration tests for running Hibernate ORM in the Java module pa
|
|||||||
|
|
||||||
apply from: rootProject.file( 'gradle/java-module.gradle' )
|
apply from: rootProject.file( 'gradle/java-module.gradle' )
|
||||||
|
|
||||||
|
// See https://docs.gradle.org/6.7.1/userguide/java_testing.html#blackbox_integration_testing
|
||||||
|
// See https://docs.gradle.org/6.7.1/samples/sample_java_modules_multi_project_with_integration_tests.html
|
||||||
java.modularity.inferModulePath = true
|
java.modularity.inferModulePath = true
|
||||||
|
|
||||||
// In this module, the "main" code is actually just test code that happens
|
|
||||||
// to be built independently so as to generate a Java module.
|
|
||||||
// So, let's override settings for compilation of the main code, just for this particular case.
|
|
||||||
def testJavaVersions = gradle.ext.javaVersions.test
|
|
||||||
tasks.compileJava {
|
|
||||||
if ( !gradle.ext.javaToolchainEnabled ) {
|
|
||||||
sourceCompatibility = JavaVersion.toVersion( testJavaVersions.release )
|
|
||||||
targetCompatibility = JavaVersion.toVersion( testJavaVersions.release )
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
javaCompiler = javaToolchains.compilerFor {
|
|
||||||
languageVersion = testJavaVersions.compiler
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove JDK8-only options (if any) that are incompatible with options.release
|
|
||||||
for ( it = options.compilerArgs.listIterator(); it.hasNext(); ) {
|
|
||||||
if ( it.next() in ['-source', '-target'] ) {
|
|
||||||
it.remove()
|
|
||||||
it.next()
|
|
||||||
it.remove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
options.release = testJavaVersions.release.asInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checkstyle fails for module-info
|
// Checkstyle fails for module-info
|
||||||
checkstyleMain.exclude '**/module-info.java'
|
checkstyleMain.exclude '**/module-info.java'
|
||||||
@ -44,6 +20,7 @@ checkstyleMain.exclude '**/module-info.java'
|
|||||||
dependencies {
|
dependencies {
|
||||||
api project( ':hibernate-core' )
|
api project( ':hibernate-core' )
|
||||||
api project( ':hibernate-envers' )
|
api project( ':hibernate-envers' )
|
||||||
|
api libraries.jpa
|
||||||
implementation libraries.jpa
|
implementation libraries.jpa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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>.
|
|
||||||
*/
|
|
||||||
module org.hibernate.orm.integrationtest.java.module {
|
|
||||||
exports org.hibernate.orm.integrationtest.java.module.service;
|
|
||||||
opens org.hibernate.orm.integrationtest.java.module.entity to
|
|
||||||
org.hibernate.orm.core;
|
|
||||||
|
|
||||||
requires java.persistence;
|
|
||||||
/*
|
|
||||||
* IDEA will not find the modules below because it apparently doesn't support automatic module names
|
|
||||||
* for modules in the current project.
|
|
||||||
* Everything should work fine when building from the command line, though.
|
|
||||||
*/
|
|
||||||
requires org.hibernate.orm.core;
|
|
||||||
requires org.hibernate.orm.envers;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is necessary in order to use SessionFactory,
|
|
||||||
* which extends "javax.naming.Referenceable".
|
|
||||||
* Without this, compilation as a Java module fails.
|
|
||||||
*/
|
|
||||||
requires java.naming;
|
|
||||||
}
|
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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>.
|
||||||
|
*/
|
||||||
|
module org.hibernate.orm.integrationtest.java.module.test {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main configuration, necessary for real client applications.
|
||||||
|
*/
|
||||||
|
|
||||||
|
opens org.hibernate.orm.integrationtest.java.module.test.entity to
|
||||||
|
org.hibernate.orm.core;
|
||||||
|
|
||||||
|
requires java.persistence;
|
||||||
|
// IDEA will not find the modules below because it apparently doesn't support automatic module names
|
||||||
|
// for modules in the current project.
|
||||||
|
// Everything should work fine when building from the command line, though.
|
||||||
|
requires org.hibernate.orm.core;
|
||||||
|
requires org.hibernate.orm.envers;
|
||||||
|
|
||||||
|
// Transitive dependencies that leak through the Hibernate ORM API
|
||||||
|
requires java.sql;
|
||||||
|
requires java.naming; // SessionFactory extends "javax.naming.Referenceable"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test-only configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
opens org.hibernate.orm.integrationtest.java.module.test to junit;
|
||||||
|
requires junit;
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.envers.boot.internal.EnversIntegrator;
|
import org.hibernate.envers.boot.internal.EnversIntegrator;
|
||||||
import org.hibernate.orm.integrationtest.java.module.service.AuthorService;
|
import org.hibernate.orm.integrationtest.java.module.test.service.AuthorService;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
import org.hibernate.boot.archive.scan.internal.StandardScanner;
|
import org.hibernate.boot.archive.scan.internal.StandardScanner;
|
||||||
import org.hibernate.boot.archive.scan.spi.ClassDescriptor;
|
import org.hibernate.boot.archive.scan.spi.ClassDescriptor;
|
||||||
import org.hibernate.boot.archive.scan.spi.ScanResult;
|
import org.hibernate.boot.archive.scan.spi.ScanResult;
|
||||||
import org.hibernate.orm.integrationtest.java.module.entity.Author;
|
import org.hibernate.orm.integrationtest.java.module.test.entity.Author;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.integrationtest.java.module.entity;
|
package org.hibernate.orm.integrationtest.java.module.test.entity;
|
||||||
|
|
||||||
import javax.persistence.Basic;
|
import javax.persistence.Basic;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
@ -4,7 +4,7 @@
|
|||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.integrationtest.java.module.service;
|
package org.hibernate.orm.integrationtest.java.module.test.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -14,7 +14,7 @@
|
|||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.envers.AuditReader;
|
import org.hibernate.envers.AuditReader;
|
||||||
import org.hibernate.envers.AuditReaderFactory;
|
import org.hibernate.envers.AuditReaderFactory;
|
||||||
import org.hibernate.orm.integrationtest.java.module.entity.Author;
|
import org.hibernate.orm.integrationtest.java.module.test.entity.Author;
|
||||||
|
|
||||||
public class AuthorService implements AutoCloseable {
|
public class AuthorService implements AutoCloseable {
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||||
version="1.0">
|
version="1.0">
|
||||||
<persistence-unit name="primaryPU">
|
<persistence-unit name="primaryPU">
|
||||||
<class>org.hibernate.orm.integrationtest.java.module.entity.Author</class>
|
<class>org.hibernate.orm.integrationtest.java.module.test.entity.Author</class>
|
||||||
<properties>
|
<properties>
|
||||||
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
|
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
|
||||||
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
|
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
|
Loading…
x
Reference in New Issue
Block a user