HHH-10267 - Support defining lazy attribute fetch groups
This commit is contained in:
parent
6afc759bf3
commit
1e44e7420b
|
@ -132,8 +132,7 @@ public abstract class AbstractEntityInsertAction extends EntityAction {
|
|||
LockMode.WRITE,
|
||||
isExecuted,
|
||||
getPersister(),
|
||||
isVersionIncrementDisabled,
|
||||
false
|
||||
isVersionIncrementDisabled
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* For use with bytecode-enhanced lazy-loading support.
|
||||
* <p/>
|
||||
* Identifies grouping for performing lazy attribute loading. By default all
|
||||
* non-collection attributes are loaded in one group named {@code "DEFAULT"}.
|
||||
* This annotation allows defining different groups of attributes to be
|
||||
* initialized together when access one attribute in the group.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@java.lang.annotation.Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface LazyGroup {
|
||||
String value();
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.bytecode.enhance.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
||||
|
@ -20,7 +21,7 @@ public interface LazyPropertyInitializer {
|
|||
/**
|
||||
* Marker value for uninitialized properties.
|
||||
*/
|
||||
public static final Serializable UNFETCHED_PROPERTY = new Serializable() {
|
||||
Serializable UNFETCHED_PROPERTY = new Serializable() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<lazy>";
|
||||
|
@ -31,6 +32,11 @@ public interface LazyPropertyInitializer {
|
|||
}
|
||||
};
|
||||
|
||||
interface InterceptorImplementor {
|
||||
Set<String> getInitializedLazyAttributeNames();
|
||||
void attributeInitialized(String name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the property, and return its new value.
|
||||
*
|
||||
|
@ -40,6 +46,6 @@ public interface LazyPropertyInitializer {
|
|||
*
|
||||
* @return ?
|
||||
*/
|
||||
public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session);
|
||||
Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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.bytecode.enhance.spi.interceptor;
|
||||
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
/**
|
||||
* Descriptor for an attribute which is enabled for bytecode lazy fetching
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LazyAttributeDescriptor {
|
||||
public static LazyAttributeDescriptor from(
|
||||
Property property,
|
||||
int attributeIndex,
|
||||
int lazyIndex) {
|
||||
String fetchGroupName = property.getLazyGroup();
|
||||
if ( fetchGroupName == null ) {
|
||||
fetchGroupName = property.getType().isCollectionType()
|
||||
? property.getName()
|
||||
: "DEFAULT";
|
||||
}
|
||||
|
||||
return new LazyAttributeDescriptor(
|
||||
attributeIndex,
|
||||
lazyIndex,
|
||||
property.getName(),
|
||||
property.getType(),
|
||||
fetchGroupName
|
||||
);
|
||||
}
|
||||
|
||||
private final int attributeIndex;
|
||||
private final int lazyIndex;
|
||||
private final String name;
|
||||
private final Type type;
|
||||
private final String fetchGroupName;
|
||||
|
||||
private LazyAttributeDescriptor(
|
||||
int attributeIndex,
|
||||
int lazyIndex,
|
||||
String name,
|
||||
Type type,
|
||||
String fetchGroupName) {
|
||||
assert attributeIndex >= lazyIndex;
|
||||
this.attributeIndex = attributeIndex;
|
||||
this.lazyIndex = lazyIndex;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.fetchGroupName = fetchGroupName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the index of the attribute in terms of its position in the entity persister
|
||||
*
|
||||
* @return The persister attribute index
|
||||
*/
|
||||
public int getAttributeIndex() {
|
||||
return attributeIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the index of the attribute in terms of its position withing the lazy attributes of the persister
|
||||
*
|
||||
* @return The persister lazy attribute index
|
||||
*/
|
||||
public int getLazyIndex() {
|
||||
return lazyIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the name of the attribute
|
||||
*
|
||||
* @return The attribute name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the attribute's type
|
||||
*
|
||||
* @return The attribute type
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to the name of the fetch group to which the attribute belongs
|
||||
*
|
||||
* @return The name of the fetch group the attribute belongs to
|
||||
*/
|
||||
public String getFetchGroupName() {
|
||||
return fetchGroupName;
|
||||
}
|
||||
}
|
|
@ -9,14 +9,16 @@ package org.hibernate.bytecode.enhance.spi.interceptor;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
|
||||
import org.hibernate.bytecode.enhance.spi.CollectionTracker;
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer.InterceptorImplementor;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.Helper.Consumer;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.Helper.LazyInitializationWork;
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||
import org.hibernate.engine.spi.SelfDirtinessTracker;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
@ -29,29 +31,30 @@ import org.jboss.logging.Logger;
|
|||
* Interceptor that loads attributes lazily
|
||||
*
|
||||
* @author Luis Barreiro
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LazyAttributeLoadingInterceptor implements PersistentAttributeInterceptor, Consumer {
|
||||
public class LazyAttributeLoadingInterceptor
|
||||
implements PersistentAttributeInterceptor, Consumer, InterceptorImplementor {
|
||||
private static final Logger log = Logger.getLogger( LazyAttributeLoadingInterceptor.class );
|
||||
|
||||
private transient SessionImplementor session;
|
||||
|
||||
private final Set<String> lazyFields;
|
||||
private final String entityName;
|
||||
private final Set<String> lazyFields;
|
||||
|
||||
private String sessionFactoryUuid;
|
||||
private Set<String> initializedLazyFields;
|
||||
|
||||
private transient SessionImplementor session;
|
||||
private boolean allowLoadOutsideTransaction;
|
||||
private String sessionFactoryUuid;
|
||||
|
||||
private final SimpleFieldTracker initializedFields = new SimpleFieldTracker();
|
||||
|
||||
public LazyAttributeLoadingInterceptor(SessionImplementor session, Set<String> lazyFields, String entityName) {
|
||||
this.session = session;
|
||||
this.lazyFields = lazyFields;
|
||||
public LazyAttributeLoadingInterceptor(
|
||||
String entityName,
|
||||
Set<String> lazyFields,
|
||||
SessionImplementor session) {
|
||||
this.entityName = entityName;
|
||||
this.lazyFields = lazyFields;
|
||||
|
||||
this.allowLoadOutsideTransaction = session.getFactory().getSessionFactoryOptions().isInitializeLazyStateOutsideTransactionsEnabled();
|
||||
if ( this.allowLoadOutsideTransaction ) {
|
||||
this.sessionFactoryUuid = session.getFactory().getUuid();
|
||||
}
|
||||
setSession( session );
|
||||
}
|
||||
|
||||
protected final Object intercept(Object target, String attributeName, Object value) {
|
||||
|
@ -77,8 +80,6 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
final Object[] loadedState = null;
|
||||
// 2) does a row exist in the db for this entity?
|
||||
final boolean existsInDb = true;
|
||||
// NOTE2: the final boolean is 'lazyPropertiesAreUnfetched' which is another
|
||||
// place where a "single lazy fetch group" shows up
|
||||
session.getPersistenceContext().addEntity(
|
||||
target,
|
||||
Status.READ_ONLY,
|
||||
|
@ -88,7 +89,6 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
LockMode.NONE,
|
||||
existsInDb,
|
||||
persister,
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
@ -100,7 +100,6 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
session
|
||||
);
|
||||
|
||||
initializedFields.add( attributeName );
|
||||
takeCollectionSizeSnapshot( target, attributeName, loadedValue );
|
||||
return loadedValue;
|
||||
}
|
||||
|
@ -120,6 +119,12 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
|
||||
public final void setSession(SessionImplementor session) {
|
||||
this.session = session;
|
||||
if ( session != null && !allowLoadOutsideTransaction ) {
|
||||
this.allowLoadOutsideTransaction = session.getFactory().getSessionFactoryOptions().isInitializeLazyStateOutsideTransactionsEnabled();
|
||||
if ( this.allowLoadOutsideTransaction ) {
|
||||
this.sessionFactoryUuid = session.getFactory().getUuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void unsetSession() {
|
||||
|
@ -127,28 +132,35 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
}
|
||||
|
||||
public boolean isAttributeLoaded(String fieldName) {
|
||||
return lazyFields == null || !lazyFields.contains( fieldName ) || initializedFields.contains( fieldName );
|
||||
return !isLazyAttribute( fieldName ) || isInitializedLazyField( fieldName );
|
||||
}
|
||||
|
||||
private boolean isLazyAttribute(String fieldName) {
|
||||
return lazyFields == null || lazyFields.contains( fieldName );
|
||||
}
|
||||
|
||||
private boolean isInitializedLazyField(String fieldName) {
|
||||
return initializedLazyFields != null && initializedLazyFields.contains( fieldName );
|
||||
}
|
||||
|
||||
public boolean hasAnyUninitializedAttributes() {
|
||||
if ( lazyFields != null ) {
|
||||
for ( String fieldName : lazyFields ) {
|
||||
if ( !initializedFields.contains( fieldName ) ) {
|
||||
return true;
|
||||
}
|
||||
if ( lazyFields == null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( initializedLazyFields == null ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for ( String fieldName : lazyFields ) {
|
||||
if ( !initializedLazyFields.contains( fieldName ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setLoaded(String attributeName) {
|
||||
initializedFields.add( attributeName );
|
||||
}
|
||||
|
||||
public String[] getiInitializedFields() {
|
||||
return initializedFields.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LazyAttributeLoader(entityName=" + entityName + " ,lazyFields=" + lazyFields + ')';
|
||||
|
@ -174,7 +186,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public boolean writeBoolean(Object obj, String name, boolean oldValue, boolean newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -187,7 +199,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public byte writeByte(Object obj, String name, byte oldValue, byte newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -200,7 +212,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public char writeChar(Object obj, String name, char oldValue, char newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -213,7 +225,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public short writeShort(Object obj, String name, short oldValue, short newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -226,7 +238,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public int writeInt(Object obj, String name, int oldValue, int newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -239,7 +251,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public float writeFloat(Object obj, String name, float oldValue, float newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -252,7 +264,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public double writeDouble(Object obj, String name, double oldValue, double newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -265,7 +277,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public long writeLong(Object obj, String name, long oldValue, long newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -278,7 +290,7 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
@Override
|
||||
public Object writeObject(Object obj, String name, Object oldValue, Object newValue) {
|
||||
if ( lazyFields != null && lazyFields.contains( name ) ) {
|
||||
initializedFields.add( name );
|
||||
attributeInitialized( name );
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
@ -297,4 +309,21 @@ public class LazyAttributeLoadingInterceptor implements PersistentAttributeInter
|
|||
public String getSessionFactoryUuid() {
|
||||
return sessionFactoryUuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attributeInitialized(String name) {
|
||||
if ( !isLazyAttribute( name ) ) {
|
||||
return;
|
||||
}
|
||||
if ( initializedLazyFields == null ) {
|
||||
initializedLazyFields = new HashSet<String>();
|
||||
}
|
||||
initializedLazyFields.add( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getInitializedLazyAttributeNames() {
|
||||
return initializedLazyFields == null ? Collections.<String>emptySet() : initializedLazyFields;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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.bytecode.enhance.spi.interceptor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
|
||||
/**
|
||||
* Information about all of the bytecode lazy attributes for an entity
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LazyAttributesMetadata implements Serializable {
|
||||
/**
|
||||
* Build a LazyFetchGroupMetadata based on the attributes defined for the
|
||||
* PersistentClass
|
||||
*
|
||||
* @param mappedEntity The entity definition
|
||||
*
|
||||
* @return The built LazyFetchGroupMetadata
|
||||
*/
|
||||
public static LazyAttributesMetadata from(PersistentClass mappedEntity) {
|
||||
final Map<String, LazyAttributeDescriptor> lazyAttributeDescriptorMap = new LinkedHashMap<String, LazyAttributeDescriptor>();
|
||||
final Map<String, Set<String>> fetchGroupToAttributesMap = new HashMap<String, Set<String>>();
|
||||
|
||||
int i = -1;
|
||||
int x = 0;
|
||||
final Iterator itr = mappedEntity.getPropertyClosureIterator();
|
||||
while ( itr.hasNext() ) {
|
||||
i++;
|
||||
final Property property = (Property) itr.next();
|
||||
if ( property.isLazy() ) {
|
||||
final LazyAttributeDescriptor lazyAttributeDescriptor = LazyAttributeDescriptor.from( property, i, x++ );
|
||||
lazyAttributeDescriptorMap.put( lazyAttributeDescriptor.getName(), lazyAttributeDescriptor );
|
||||
|
||||
Set<String> attributeSet = fetchGroupToAttributesMap.get( lazyAttributeDescriptor.getFetchGroupName() );
|
||||
if ( attributeSet == null ) {
|
||||
attributeSet = new LinkedHashSet<String>();
|
||||
fetchGroupToAttributesMap.put( lazyAttributeDescriptor.getFetchGroupName(), attributeSet );
|
||||
}
|
||||
attributeSet.add( lazyAttributeDescriptor.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( lazyAttributeDescriptorMap.isEmpty() ) {
|
||||
return new LazyAttributesMetadata( mappedEntity.getEntityName() );
|
||||
}
|
||||
|
||||
for ( Map.Entry<String, Set<String>> entry : fetchGroupToAttributesMap.entrySet() ) {
|
||||
entry.setValue( Collections.unmodifiableSet( entry.getValue() ) );
|
||||
}
|
||||
|
||||
return new LazyAttributesMetadata(
|
||||
mappedEntity.getEntityName(),
|
||||
Collections.unmodifiableMap( lazyAttributeDescriptorMap ),
|
||||
Collections.unmodifiableMap( fetchGroupToAttributesMap )
|
||||
);
|
||||
}
|
||||
|
||||
public static LazyAttributesMetadata nonEnhanced(String entityName) {
|
||||
return new LazyAttributesMetadata( entityName );
|
||||
}
|
||||
|
||||
private final String entityName;
|
||||
|
||||
private final Map<String, LazyAttributeDescriptor> lazyAttributeDescriptorMap;
|
||||
private final Map<String,Set<String>> fetchGroupToAttributeMap;
|
||||
|
||||
public LazyAttributesMetadata(String entityName) {
|
||||
this( entityName, Collections.<String, LazyAttributeDescriptor>emptyMap(), Collections.<String, Set<String>>emptyMap() );
|
||||
}
|
||||
|
||||
public LazyAttributesMetadata(
|
||||
String entityName,
|
||||
Map<String, LazyAttributeDescriptor> lazyAttributeDescriptorMap,
|
||||
Map<String, Set<String>> fetchGroupToAttributeMap) {
|
||||
this.entityName = entityName;
|
||||
this.lazyAttributeDescriptorMap = lazyAttributeDescriptorMap;
|
||||
this.fetchGroupToAttributeMap = fetchGroupToAttributeMap;
|
||||
}
|
||||
|
||||
public String getEntityName() {
|
||||
return entityName;
|
||||
}
|
||||
|
||||
public boolean hasLazyAttributes() {
|
||||
return !lazyAttributeDescriptorMap.isEmpty();
|
||||
}
|
||||
|
||||
public int lazyAttributeCount() {
|
||||
return lazyAttributeDescriptorMap.size();
|
||||
}
|
||||
|
||||
public Set<String> getLazyAttributeNames() {
|
||||
return lazyAttributeDescriptorMap.keySet();
|
||||
}
|
||||
|
||||
public Set<String> getFetchGroupNames() {
|
||||
return fetchGroupToAttributeMap.keySet();
|
||||
}
|
||||
|
||||
public boolean isLazyAttribute(String attributeName) {
|
||||
return lazyAttributeDescriptorMap.containsKey( attributeName );
|
||||
}
|
||||
|
||||
public String getFetchGroupName(String attributeName) {
|
||||
return lazyAttributeDescriptorMap.get( attributeName ).getFetchGroupName();
|
||||
}
|
||||
|
||||
public Set<String> getAttributesInFetchGroup(String fetchGroupName) {
|
||||
return fetchGroupToAttributeMap.get( fetchGroupName );
|
||||
}
|
||||
|
||||
public List<LazyAttributeDescriptor> getFetchGroupAttributeDescriptors(String groupName) {
|
||||
final List<LazyAttributeDescriptor> list = new ArrayList<LazyAttributeDescriptor>();
|
||||
for ( String attributeName : fetchGroupToAttributeMap.get( groupName ) ) {
|
||||
list.add( lazyAttributeDescriptorMap.get( attributeName ) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public Set<String> getAttributesInSameFetchGroup(String attributeName) {
|
||||
final String fetchGroupName = getFetchGroupName( attributeName );
|
||||
return getAttributesInFetchGroup( fetchGroupName );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.bytecode.enhance.spi.interceptor;
|
||||
|
||||
/**
|
||||
* Information about a particular bytecode lazy attribute grouping.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface LazyFetchGroupMetadata {
|
||||
/**
|
||||
* Access to the name of the fetch group.
|
||||
*
|
||||
* @return The fetch group name
|
||||
*/
|
||||
String getName();
|
||||
}
|
|
@ -9,6 +9,7 @@ package org.hibernate.bytecode.spi;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributesMetadata;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
||||
/**
|
||||
|
@ -32,11 +33,12 @@ public interface BytecodeEnhancementMetadata {
|
|||
*/
|
||||
boolean isEnhancedForLazyLoading();
|
||||
|
||||
LazyAttributesMetadata getLazyAttributesMetadata();
|
||||
|
||||
/**
|
||||
* Build and inject an interceptor instance into the enhanced entity.
|
||||
*
|
||||
* @param entity The entity into which built interceptor should be injected
|
||||
* @param uninitializedFieldNames The name of fields marked as lazy
|
||||
* @param session The session to which the entity instance belongs.
|
||||
*
|
||||
* @return The built and injected interceptor
|
||||
|
@ -45,7 +47,6 @@ public interface BytecodeEnhancementMetadata {
|
|||
*/
|
||||
LazyAttributeLoadingInterceptor injectInterceptor(
|
||||
Object entity,
|
||||
Set<String> uninitializedFieldNames,
|
||||
SessionImplementor session) throws NotInstrumentedException;
|
||||
|
||||
/**
|
||||
|
@ -58,4 +59,6 @@ public interface BytecodeEnhancementMetadata {
|
|||
* @throws NotInstrumentedException Thrown if {@link #isEnhancedForLazyLoading()} returns {@code false}
|
||||
*/
|
||||
LazyAttributeLoadingInterceptor extractInterceptor(Object entity) throws NotInstrumentedException;
|
||||
|
||||
boolean hasUnFetchedAttributes(Object entity);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ public interface CacheEntry extends Serializable {
|
|||
*
|
||||
* @return true/false
|
||||
*/
|
||||
public boolean isReferenceEntry();
|
||||
boolean isReferenceEntry();
|
||||
|
||||
/**
|
||||
* Hibernate stores all entries pertaining to a given entity hierarchy in a single region. This attribute
|
||||
|
@ -28,21 +28,14 @@ public interface CacheEntry extends Serializable {
|
|||
*
|
||||
* @return The entry's exact entity type.
|
||||
*/
|
||||
public String getSubclass();
|
||||
String getSubclass();
|
||||
|
||||
/**
|
||||
* Retrieves the version (optimistic locking) associated with this cache entry.
|
||||
*
|
||||
* @return The version of the entity represented by this entry
|
||||
*/
|
||||
public Object getVersion();
|
||||
|
||||
/**
|
||||
* Does the represented data contain any un-fetched attribute values?
|
||||
*
|
||||
* @return true/false
|
||||
*/
|
||||
public boolean areLazyPropertiesUnfetched();
|
||||
Object getVersion();
|
||||
|
||||
/**
|
||||
* Get the underlying disassembled state
|
||||
|
@ -53,6 +46,5 @@ public interface CacheEntry extends Serializable {
|
|||
*
|
||||
* @return The disassembled state
|
||||
*/
|
||||
public Serializable[] getDisassembledState();
|
||||
|
||||
Serializable[] getDisassembledState();
|
||||
}
|
||||
|
|
|
@ -60,12 +60,6 @@ public class ReferenceCacheEntryImpl implements CacheEntry {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areLazyPropertiesUnfetched() {
|
||||
// reference data cannot define lazy attributes
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable[] getDisassembledState() {
|
||||
// reference data is not disassembled into the cache
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.cache.spi.entry;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -19,6 +20,7 @@ import org.hibernate.event.spi.EventType;
|
|||
import org.hibernate.event.spi.PreLoadEvent;
|
||||
import org.hibernate.event.spi.PreLoadEventListener;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.TypeHelper;
|
||||
|
||||
|
@ -30,7 +32,6 @@ import org.hibernate.type.TypeHelper;
|
|||
public class StandardCacheEntryImpl implements CacheEntry {
|
||||
private final Serializable[] disassembledState;
|
||||
private final String subclass;
|
||||
private final boolean lazyPropertiesAreUnfetched;
|
||||
private final Object version;
|
||||
|
||||
/**
|
||||
|
@ -38,7 +39,6 @@ public class StandardCacheEntryImpl implements CacheEntry {
|
|||
*
|
||||
* @param state The extracted state
|
||||
* @param persister The entity persister
|
||||
* @param unfetched Are any values present in state unfetched?
|
||||
* @param version The current version (if versioned)
|
||||
* @param session The originating session
|
||||
* @param owner The owner
|
||||
|
@ -48,11 +48,9 @@ public class StandardCacheEntryImpl implements CacheEntry {
|
|||
public StandardCacheEntryImpl(
|
||||
final Object[] state,
|
||||
final EntityPersister persister,
|
||||
final boolean unfetched,
|
||||
final Object version,
|
||||
final SessionImplementor session,
|
||||
final Object owner)
|
||||
throws HibernateException {
|
||||
final Object owner) throws HibernateException {
|
||||
// disassembled state gets put in a new array (we write to cache by value!)
|
||||
this.disassembledState = TypeHelper.disassemble(
|
||||
state,
|
||||
|
@ -62,14 +60,12 @@ public class StandardCacheEntryImpl implements CacheEntry {
|
|||
owner
|
||||
);
|
||||
subclass = persister.getEntityName();
|
||||
lazyPropertiesAreUnfetched = unfetched || !persister.isLazyPropertiesCacheable();
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
StandardCacheEntryImpl(Serializable[] state, String subclass, boolean unfetched, Object version) {
|
||||
StandardCacheEntryImpl(Serializable[] state, String subclass, Object version) {
|
||||
this.disassembledState = state;
|
||||
this.subclass = subclass;
|
||||
this.lazyPropertiesAreUnfetched = unfetched;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
|
@ -93,11 +89,6 @@ public class StandardCacheEntryImpl implements CacheEntry {
|
|||
return subclass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areLazyPropertiesUnfetched() {
|
||||
return lazyPropertiesAreUnfetched;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getVersion() {
|
||||
return version;
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.cache.spi.entry;
|
|||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -21,6 +22,9 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StructuredCacheEntry implements CacheEntryStructure {
|
||||
public static final String SUBCLASS_KEY = "_subclass";
|
||||
public static final String VERSION_KEY = "_version";
|
||||
|
||||
private EntityPersister persister;
|
||||
|
||||
/**
|
||||
|
@ -33,18 +37,18 @@ public class StructuredCacheEntry implements CacheEntryStructure {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object destructure(Object structured, SessionFactoryImplementor factory) {
|
||||
final Map map = (Map) structured;
|
||||
final boolean lazyPropertiesUnfetched = (Boolean) map.get( "_lazyPropertiesUnfetched" );
|
||||
final String subclass = (String) map.get( "_subclass" );
|
||||
final Object version = map.get( "_version" );
|
||||
final String subclass = (String) map.get( SUBCLASS_KEY );
|
||||
final Object version = map.get( VERSION_KEY );
|
||||
final EntityPersister subclassPersister = factory.getEntityPersister( subclass );
|
||||
final String[] names = subclassPersister.getPropertyNames();
|
||||
final Serializable[] state = new Serializable[names.length];
|
||||
for ( int i = 0; i < names.length; i++ ) {
|
||||
state[i] = (Serializable) map.get( names[i] );
|
||||
}
|
||||
return new StandardCacheEntryImpl( state, subclass, lazyPropertiesUnfetched, version );
|
||||
return new StandardCacheEntryImpl( state, subclass, version );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,9 +57,8 @@ public class StructuredCacheEntry implements CacheEntryStructure {
|
|||
final CacheEntry entry = (CacheEntry) item;
|
||||
final String[] names = persister.getPropertyNames();
|
||||
final Map map = new HashMap( names.length + 3, 1f );
|
||||
map.put( "_subclass", entry.getSubclass() );
|
||||
map.put( "_version", entry.getVersion() );
|
||||
map.put( "_lazyPropertiesUnfetched", entry.areLazyPropertiesUnfetched() );
|
||||
map.put( SUBCLASS_KEY, entry.getSubclass() );
|
||||
map.put( VERSION_KEY, entry.getVersion() );
|
||||
for ( int i=0; i<names.length; i++ ) {
|
||||
map.put( names[i], entry.getDisassembledState()[i] );
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ import org.hibernate.annotations.Formula;
|
|||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.hibernate.annotations.GenericGenerators;
|
||||
import org.hibernate.annotations.Index;
|
||||
import org.hibernate.annotations.LazyGroup;
|
||||
import org.hibernate.annotations.LazyToOne;
|
||||
import org.hibernate.annotations.LazyToOneOption;
|
||||
import org.hibernate.annotations.ListIndexBase;
|
||||
|
@ -1666,6 +1667,11 @@ public final class AnnotationBinder {
|
|||
|| property.isAnnotationPresent( EmbeddedId.class ) );
|
||||
propertyBinder.setId( isId );
|
||||
|
||||
final LazyGroup lazyGroupAnnotation = property.getAnnotation( LazyGroup.class );
|
||||
if ( lazyGroupAnnotation != null ) {
|
||||
propertyBinder.setLazyGroup( lazyGroupAnnotation.value() );
|
||||
}
|
||||
|
||||
if ( property.isAnnotationPresent( Version.class ) ) {
|
||||
if ( isIdentifierMapper ) {
|
||||
throw new AnnotationException(
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.hibernate.annotations.ForeignKey;
|
|||
import org.hibernate.annotations.Immutable;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.hibernate.annotations.LazyGroup;
|
||||
import org.hibernate.annotations.Loader;
|
||||
import org.hibernate.annotations.ManyToAny;
|
||||
import org.hibernate.annotations.OptimisticLock;
|
||||
|
@ -525,6 +526,10 @@ public abstract class CollectionBinder {
|
|||
collection.setOrphanDelete( true );
|
||||
}
|
||||
binder.setLazy( collection.isLazy() );
|
||||
final LazyGroup lazyGroupAnnotation = property.getAnnotation( LazyGroup.class );
|
||||
if ( lazyGroupAnnotation != null ) {
|
||||
binder.setLazyGroup( lazyGroupAnnotation.value() );
|
||||
}
|
||||
binder.setAccessType( accessType );
|
||||
binder.setProperty( property );
|
||||
binder.setInsertable( insertable );
|
||||
|
|
|
@ -58,6 +58,7 @@ public class PropertyBinder {
|
|||
private String name;
|
||||
private String returnedClassName;
|
||||
private boolean lazy;
|
||||
private String lazyGroup;
|
||||
private AccessType accessType;
|
||||
private Ejb3Column[] columns;
|
||||
private PropertyHolder holder;
|
||||
|
@ -115,6 +116,10 @@ public class PropertyBinder {
|
|||
this.lazy = lazy;
|
||||
}
|
||||
|
||||
public void setLazyGroup(String lazyGroup) {
|
||||
this.lazyGroup = lazyGroup;
|
||||
}
|
||||
|
||||
public void setAccessType(AccessType accessType) {
|
||||
this.accessType = accessType;
|
||||
}
|
||||
|
@ -262,6 +267,7 @@ public class PropertyBinder {
|
|||
prop.setName( name );
|
||||
prop.setValue( value );
|
||||
prop.setLazy( lazy );
|
||||
prop.setLazyGroup( lazyGroup );
|
||||
prop.setCascade( cascade );
|
||||
prop.setPropertyAccessorName( accessType.getType() );
|
||||
|
||||
|
|
|
@ -90,10 +90,10 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
final EntityMode entityMode,
|
||||
final String tenantId,
|
||||
final boolean disableVersionIncrement,
|
||||
final boolean lazyPropertiesAreUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
this( status, loadedState, rowId, id, version, lockMode, existsInDatabase,
|
||||
persister,disableVersionIncrement, lazyPropertiesAreUnfetched, persistenceContext );
|
||||
persister,disableVersionIncrement, persistenceContext
|
||||
);
|
||||
}
|
||||
|
||||
public AbstractEntityEntry(
|
||||
|
@ -106,7 +106,6 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
final boolean existsInDatabase,
|
||||
final EntityPersister persister,
|
||||
final boolean disableVersionIncrement,
|
||||
final boolean lazyPropertiesAreUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
setCompressedValue( EnumState.STATUS, status );
|
||||
// not useful strictly speaking but more explicit
|
||||
|
@ -121,7 +120,6 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
this.version=version;
|
||||
setCompressedValue( EnumState.LOCK_MODE, lockMode );
|
||||
setCompressedValue( BooleanState.IS_BEING_REPLICATED, disableVersionIncrement );
|
||||
setCompressedValue( BooleanState.LOADED_WITH_LAZY_PROPERTIES_UNFETCHED, lazyPropertiesAreUnfetched );
|
||||
this.persister=persister;
|
||||
this.persistenceContext = persistenceContext;
|
||||
}
|
||||
|
@ -142,7 +140,6 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
final LockMode lockMode,
|
||||
final boolean existsInDatabase,
|
||||
final boolean isBeingReplicated,
|
||||
final boolean loadedWithLazyPropertiesUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
this.persister = ( factory == null ? null : factory.getEntityPersister( entityName ) );
|
||||
this.id = id;
|
||||
|
@ -154,7 +151,6 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
setCompressedValue( EnumState.LOCK_MODE, lockMode );
|
||||
setCompressedValue( BooleanState.EXISTS_IN_DATABASE, existsInDatabase );
|
||||
setCompressedValue( BooleanState.IS_BEING_REPLICATED, isBeingReplicated );
|
||||
setCompressedValue( BooleanState.LOADED_WITH_LAZY_PROPERTIES_UNFETCHED, loadedWithLazyPropertiesUnfetched );
|
||||
this.rowId = null; // this is equivalent to the old behavior...
|
||||
this.persistenceContext = persistenceContext;
|
||||
}
|
||||
|
@ -410,11 +406,6 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
'(' + getStatus() + ')';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoadedWithLazyPropertiesUnfetched() {
|
||||
return getCompressedValue( BooleanState.LOADED_WITH_LAZY_PROPERTIES_UNFETCHED );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
final Status previousStatus = getPreviousStatus();
|
||||
|
@ -429,7 +420,6 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
oos.writeObject( getLockMode().toString() );
|
||||
oos.writeBoolean( isExistsInDatabase() );
|
||||
oos.writeBoolean( isBeingReplicated() );
|
||||
oos.writeBoolean( isLoadedWithLazyPropertiesUnfetched() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -593,8 +583,7 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
|
|||
protected enum BooleanState {
|
||||
|
||||
EXISTS_IN_DATABASE(13),
|
||||
IS_BEING_REPLICATED(14),
|
||||
LOADED_WITH_LAZY_PROPERTIES_UNFETCHED(15);
|
||||
IS_BEING_REPLICATED(14);
|
||||
|
||||
private final int offset;
|
||||
private final int mask;
|
||||
|
|
|
@ -50,7 +50,6 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
|
|||
final EntityMode entityMode,
|
||||
final String tenantId,
|
||||
final boolean disableVersionIncrement,
|
||||
final boolean lazyPropertiesAreUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
this(
|
||||
status,
|
||||
|
@ -62,7 +61,6 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
|
|||
existsInDatabase,
|
||||
persister,
|
||||
disableVersionIncrement,
|
||||
lazyPropertiesAreUnfetched,
|
||||
// purposefully do not pass along the session/persistence-context : HHH-10251
|
||||
null
|
||||
);
|
||||
|
@ -78,7 +76,6 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
|
|||
final boolean existsInDatabase,
|
||||
final EntityPersister persister,
|
||||
final boolean disableVersionIncrement,
|
||||
final boolean lazyPropertiesAreUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
|
||||
super(
|
||||
|
@ -91,7 +88,6 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
|
|||
existsInDatabase,
|
||||
persister,
|
||||
disableVersionIncrement,
|
||||
lazyPropertiesAreUnfetched,
|
||||
// purposefully do not pass along the session/persistence-context : HHH-10251
|
||||
null
|
||||
);
|
||||
|
@ -113,12 +109,11 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
|
|||
final LockMode lockMode,
|
||||
final boolean existsInDatabase,
|
||||
final boolean isBeingReplicated,
|
||||
final boolean loadedWithLazyPropertiesUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
|
||||
super( factory, entityName, id, status, previousStatus, loadedState, deletedState,
|
||||
version, lockMode, existsInDatabase, isBeingReplicated, loadedWithLazyPropertiesUnfetched,
|
||||
persistenceContext );
|
||||
version, lockMode, existsInDatabase, isBeingReplicated, persistenceContext
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -166,7 +161,6 @@ public final class ImmutableEntityEntry extends AbstractEntityEntry {
|
|||
LockMode.valueOf( (String) ois.readObject() ),
|
||||
ois.readBoolean(),
|
||||
ois.readBoolean(),
|
||||
ois.readBoolean(),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
package org.hibernate.engine.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.spi.EntityEntry;
|
||||
|
@ -43,7 +44,6 @@ public class ImmutableEntityEntryFactory implements EntityEntryFactory {
|
|||
boolean existsInDatabase,
|
||||
EntityPersister persister,
|
||||
boolean disableVersionIncrement,
|
||||
boolean lazyPropertiesAreUnfetched,
|
||||
PersistenceContext persistenceContext) {
|
||||
return new ImmutableEntityEntry(
|
||||
status,
|
||||
|
@ -55,7 +55,6 @@ public class ImmutableEntityEntryFactory implements EntityEntryFactory {
|
|||
existsInDatabase,
|
||||
persister,
|
||||
disableVersionIncrement,
|
||||
lazyPropertiesAreUnfetched,
|
||||
persistenceContext
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
* @author Sanne Grinovero <sanne@hibernate.org>
|
||||
*/
|
||||
public final class MutableEntityEntry extends AbstractEntityEntry {
|
||||
|
||||
/**
|
||||
* @deprecated the tenantId and entityMode parameters where removed: this constructor accepts but ignores them.
|
||||
* Use the other constructor!
|
||||
|
@ -45,10 +44,10 @@ public final class MutableEntityEntry extends AbstractEntityEntry {
|
|||
final EntityMode entityMode,
|
||||
final String tenantId,
|
||||
final boolean disableVersionIncrement,
|
||||
final boolean lazyPropertiesAreUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
this( status, loadedState, rowId, id, version, lockMode, existsInDatabase,
|
||||
persister,disableVersionIncrement, lazyPropertiesAreUnfetched, persistenceContext );
|
||||
persister,disableVersionIncrement, persistenceContext
|
||||
);
|
||||
}
|
||||
|
||||
public MutableEntityEntry(
|
||||
|
@ -61,11 +60,10 @@ public final class MutableEntityEntry extends AbstractEntityEntry {
|
|||
final boolean existsInDatabase,
|
||||
final EntityPersister persister,
|
||||
final boolean disableVersionIncrement,
|
||||
final boolean lazyPropertiesAreUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
|
||||
super( status, loadedState, rowId, id, version, lockMode, existsInDatabase, persister,
|
||||
disableVersionIncrement, lazyPropertiesAreUnfetched, persistenceContext );
|
||||
disableVersionIncrement, persistenceContext
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,15 +82,12 @@ public final class MutableEntityEntry extends AbstractEntityEntry {
|
|||
final LockMode lockMode,
|
||||
final boolean existsInDatabase,
|
||||
final boolean isBeingReplicated,
|
||||
final boolean loadedWithLazyPropertiesUnfetched,
|
||||
final PersistenceContext persistenceContext) {
|
||||
|
||||
super( factory, entityName, id, status, previousStatus, loadedState, deletedState,
|
||||
version, lockMode, existsInDatabase, isBeingReplicated, loadedWithLazyPropertiesUnfetched,
|
||||
persistenceContext );
|
||||
version, lockMode, existsInDatabase, isBeingReplicated, persistenceContext
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom deserialization routine used during deserialization of a
|
||||
* Session/PersistenceContext for increased performance.
|
||||
|
@ -124,7 +119,6 @@ public final class MutableEntityEntry extends AbstractEntityEntry {
|
|||
LockMode.valueOf( (String) ois.readObject() ),
|
||||
ois.readBoolean(),
|
||||
ois.readBoolean(),
|
||||
ois.readBoolean(),
|
||||
persistenceContext
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
package org.hibernate.engine.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.spi.EntityEntry;
|
||||
|
@ -43,7 +44,6 @@ public class MutableEntityEntryFactory implements EntityEntryFactory {
|
|||
boolean existsInDatabase,
|
||||
EntityPersister persister,
|
||||
boolean disableVersionIncrement,
|
||||
boolean lazyPropertiesAreUnfetched,
|
||||
PersistenceContext persistenceContext) {
|
||||
return new MutableEntityEntry(
|
||||
status,
|
||||
|
@ -55,7 +55,6 @@ public class MutableEntityEntryFactory implements EntityEntryFactory {
|
|||
existsInDatabase,
|
||||
persister,
|
||||
disableVersionIncrement,
|
||||
lazyPropertiesAreUnfetched,
|
||||
persistenceContext
|
||||
);
|
||||
}
|
||||
|
|
|
@ -455,8 +455,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
final LockMode lockMode,
|
||||
final boolean existsInDatabase,
|
||||
final EntityPersister persister,
|
||||
final boolean disableVersionIncrement,
|
||||
boolean lazyPropertiesAreUnfetched) {
|
||||
final boolean disableVersionIncrement) {
|
||||
addEntity( entityKey, entity );
|
||||
return addEntry(
|
||||
entity,
|
||||
|
@ -468,8 +467,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
lockMode,
|
||||
existsInDatabase,
|
||||
persister,
|
||||
disableVersionIncrement,
|
||||
lazyPropertiesAreUnfetched
|
||||
disableVersionIncrement
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -484,9 +482,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
final LockMode lockMode,
|
||||
final boolean existsInDatabase,
|
||||
final EntityPersister persister,
|
||||
final boolean disableVersionIncrement,
|
||||
boolean lazyPropertiesAreUnfetched) {
|
||||
|
||||
final boolean disableVersionIncrement) {
|
||||
final EntityEntry e;
|
||||
|
||||
if( (entity instanceof ManagedEntity) && ((ManagedEntity) entity).$$_hibernate_getEntityEntry() != null && status == Status.READ_ONLY) {
|
||||
|
@ -505,7 +501,6 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
existsInDatabase,
|
||||
persister,
|
||||
disableVersionIncrement,
|
||||
lazyPropertiesAreUnfetched,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
@ -1382,8 +1377,7 @@ public class StatefulPersistenceContext implements PersistenceContext {
|
|||
oldEntry.getLockMode(),
|
||||
oldEntry.isExistsInDatabase(),
|
||||
oldEntry.getPersister(),
|
||||
oldEntry.isBeingReplicated(),
|
||||
oldEntry.isLoadedWithLazyPropertiesUnfetched()
|
||||
oldEntry.isBeingReplicated()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@ public final class TwoPhaseLoad {
|
|||
* @param rowId The rowId for the entity
|
||||
* @param object An optional instance for the entity being loaded
|
||||
* @param lockMode The lock mode
|
||||
* @param lazyPropertiesAreUnFetched Whether properties defined as lazy are yet un-fetched
|
||||
* @param session The Session
|
||||
*/
|
||||
public static void postHydrate(
|
||||
|
@ -77,7 +76,6 @@ public final class TwoPhaseLoad {
|
|||
final Object rowId,
|
||||
final Object object,
|
||||
final LockMode lockMode,
|
||||
final boolean lazyPropertiesAreUnFetched,
|
||||
final SessionImplementor session) {
|
||||
final Object version = Versioning.getVersion( values, persister );
|
||||
session.getPersistenceContext().addEntry(
|
||||
|
@ -90,8 +88,7 @@ public final class TwoPhaseLoad {
|
|||
lockMode,
|
||||
true,
|
||||
persister,
|
||||
false,
|
||||
lazyPropertiesAreUnFetched
|
||||
false
|
||||
);
|
||||
|
||||
if ( version != null && LOG.isTraceEnabled() ) {
|
||||
|
@ -264,11 +261,7 @@ public final class TwoPhaseLoad {
|
|||
persistenceContext.setEntryStatus( entityEntry, Status.MANAGED );
|
||||
}
|
||||
|
||||
persister.afterInitialize(
|
||||
entity,
|
||||
entityEntry.isLoadedWithLazyPropertiesUnfetched(),
|
||||
session
|
||||
);
|
||||
persister.afterInitialize( entity, session );
|
||||
|
||||
if ( debugEnabled ) {
|
||||
LOG.debugf(
|
||||
|
@ -317,11 +310,13 @@ public final class TwoPhaseLoad {
|
|||
}
|
||||
|
||||
private static boolean useMinimalPuts(SessionImplementor session, EntityEntry entityEntry) {
|
||||
return ( session.getFactory().getSettings().isMinimalPutsEnabled()
|
||||
&& session.getCacheMode()!=CacheMode.REFRESH )
|
||||
|| ( entityEntry.getPersister().hasLazyProperties()
|
||||
&& entityEntry.isLoadedWithLazyPropertiesUnfetched()
|
||||
&& entityEntry.getPersister().isLazyPropertiesCacheable() );
|
||||
if ( session.getFactory().getSessionFactoryOptions().isMinimalPutsEnabled() ) {
|
||||
return session.getCacheMode() != CacheMode.REFRESH;
|
||||
}
|
||||
else {
|
||||
return entityEntry.getPersister().hasLazyProperties()
|
||||
&& entityEntry.getPersister().isLazyPropertiesCacheable();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -335,7 +330,6 @@ public final class TwoPhaseLoad {
|
|||
* @param object The entity instance
|
||||
* @param persister The entity persister
|
||||
* @param lockMode The lock mode
|
||||
* @param lazyPropertiesAreUnFetched Are lazy properties still un-fetched?
|
||||
* @param session The Session
|
||||
*/
|
||||
public static void addUninitializedEntity(
|
||||
|
@ -343,7 +337,6 @@ public final class TwoPhaseLoad {
|
|||
final Object object,
|
||||
final EntityPersister persister,
|
||||
final LockMode lockMode,
|
||||
final boolean lazyPropertiesAreUnFetched,
|
||||
final SessionImplementor session) {
|
||||
session.getPersistenceContext().addEntity(
|
||||
object,
|
||||
|
@ -354,8 +347,7 @@ public final class TwoPhaseLoad {
|
|||
lockMode,
|
||||
true,
|
||||
persister,
|
||||
false,
|
||||
lazyPropertiesAreUnFetched
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -366,7 +358,6 @@ public final class TwoPhaseLoad {
|
|||
* @param object The entity instance
|
||||
* @param persister The entity persister
|
||||
* @param lockMode The lock mode
|
||||
* @param lazyPropertiesAreUnFetched Are lazy properties still un-fetched?
|
||||
* @param version The version
|
||||
* @param session The Session
|
||||
*/
|
||||
|
@ -375,7 +366,6 @@ public final class TwoPhaseLoad {
|
|||
final Object object,
|
||||
final EntityPersister persister,
|
||||
final LockMode lockMode,
|
||||
final boolean lazyPropertiesAreUnFetched,
|
||||
final Object version,
|
||||
final SessionImplementor session) {
|
||||
session.getPersistenceContext().addEntity(
|
||||
|
@ -387,8 +377,7 @@ public final class TwoPhaseLoad {
|
|||
lockMode,
|
||||
true,
|
||||
persister,
|
||||
false,
|
||||
lazyPropertiesAreUnFetched
|
||||
);
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.engine.spi;
|
|||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -124,8 +125,6 @@ public interface EntityEntry {
|
|||
@Override
|
||||
String toString();
|
||||
|
||||
boolean isLoadedWithLazyPropertiesUnfetched();
|
||||
|
||||
/**
|
||||
* Custom serialization routine used during serialization of a
|
||||
* Session/PersistenceContext for increased performance.
|
||||
|
|
|
@ -31,6 +31,5 @@ public interface EntityEntryFactory extends Serializable {
|
|||
final boolean existsInDatabase,
|
||||
final EntityPersister persister,
|
||||
final boolean disableVersionIncrement,
|
||||
final boolean lazyPropertiesAreUnfetched,
|
||||
final PersistenceContext persistenceContext);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.io.Serializable;
|
|||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -235,7 +236,7 @@ public interface PersistenceContext {
|
|||
/**
|
||||
* Adds an entity to the internal caches.
|
||||
*/
|
||||
public EntityEntry addEntity(
|
||||
EntityEntry addEntity(
|
||||
final Object entity,
|
||||
final Status status,
|
||||
final Object[] loadedState,
|
||||
|
@ -244,8 +245,7 @@ public interface PersistenceContext {
|
|||
final LockMode lockMode,
|
||||
final boolean existsInDatabase,
|
||||
final EntityPersister persister,
|
||||
final boolean disableVersionIncrement,
|
||||
boolean lazyPropertiesAreUnfetched);
|
||||
final boolean disableVersionIncrement);
|
||||
|
||||
/**
|
||||
* Generates an appropriate EntityEntry instance and adds it
|
||||
|
@ -261,8 +261,7 @@ public interface PersistenceContext {
|
|||
final LockMode lockMode,
|
||||
final boolean existsInDatabase,
|
||||
final EntityPersister persister,
|
||||
final boolean disableVersionIncrement,
|
||||
boolean lazyPropertiesAreUnfetched);
|
||||
final boolean disableVersionIncrement);
|
||||
|
||||
/**
|
||||
* Is the given collection associated with this persistence context?
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
*/
|
||||
package org.hibernate.engine.spi;
|
||||
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer.InterceptorImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface PersistentAttributeInterceptor {
|
||||
public interface PersistentAttributeInterceptor extends InterceptorImplementor {
|
||||
|
||||
public boolean readBoolean(Object obj, String name, boolean oldValue);
|
||||
|
||||
|
|
|
@ -76,8 +76,7 @@ public abstract class AbstractReassociateEventListener implements Serializable {
|
|||
LockMode.NONE,
|
||||
true,
|
||||
persister,
|
||||
false,
|
||||
true //will be ignored, using the existing Entry instead
|
||||
false
|
||||
);
|
||||
|
||||
new OnLockVisitor( source, id, object ).process( object, persister );
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.hibernate.engine.spi.CascadingAction;
|
|||
import org.hibernate.engine.spi.EntityEntry;
|
||||
import org.hibernate.engine.spi.EntityEntryExtraState;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.engine.spi.SelfDirtinessTracker;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.engine.spi.Status;
|
||||
import org.hibernate.event.spi.EventSource;
|
||||
|
@ -96,6 +97,10 @@ public abstract class AbstractSaveEventListener extends AbstractReassociateEvent
|
|||
Object anything,
|
||||
EventSource source,
|
||||
boolean requiresImmediateIdAccess) {
|
||||
if ( entity instanceof SelfDirtinessTracker ) {
|
||||
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
|
||||
}
|
||||
|
||||
EntityPersister persister = source.getEntityPersister( entityName, entity );
|
||||
Serializable generatedId = persister.getIdentifierGenerator().generate( source, entity );
|
||||
if ( generatedId == null ) {
|
||||
|
@ -241,7 +246,6 @@ public abstract class AbstractSaveEventListener extends AbstractReassociateEvent
|
|||
LockMode.WRITE,
|
||||
useIdentityColumn,
|
||||
persister,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
|
|
|
@ -113,7 +113,6 @@ public class DefaultDeleteEventListener implements DeleteEventListener {
|
|||
LockMode.NONE,
|
||||
true,
|
||||
persister,
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
|
|
@ -675,7 +675,6 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
|
|||
entity,
|
||||
subclassPersister,
|
||||
LockMode.NONE,
|
||||
entry.areLazyPropertiesUnfetched(),
|
||||
entry.getVersion(),
|
||||
session
|
||||
);
|
||||
|
@ -728,10 +727,9 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
|
|||
LockMode.NONE,
|
||||
true,
|
||||
subclassPersister,
|
||||
false,
|
||||
entry.areLazyPropertiesUnfetched()
|
||||
false
|
||||
);
|
||||
subclassPersister.afterInitialize( entity, entry.areLazyPropertiesUnfetched(), session );
|
||||
subclassPersister.afterInitialize( entity, session );
|
||||
persistenceContext.initializeNonLazyCollections();
|
||||
|
||||
//PostLoad is needed for EJB3
|
||||
|
@ -775,7 +773,6 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
|
|||
result,
|
||||
subclassPersister,
|
||||
LockMode.NONE,
|
||||
entry.areLazyPropertiesUnfetched(),
|
||||
entry.getVersion(),
|
||||
session
|
||||
);
|
||||
|
@ -822,10 +819,9 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
|
|||
LockMode.NONE,
|
||||
true,
|
||||
subclassPersister,
|
||||
false,
|
||||
entry.areLazyPropertiesUnfetched()
|
||||
false
|
||||
);
|
||||
subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session );
|
||||
subclassPersister.afterInitialize( result, session );
|
||||
persistenceContext.initializeNonLazyCollections();
|
||||
// upgrade the lock if necessary:
|
||||
//lock(result, lockMode);
|
||||
|
|
|
@ -191,8 +191,7 @@ public class DefaultReplicateEventListener extends AbstractSaveEventListener imp
|
|||
LockMode.NONE,
|
||||
true,
|
||||
persister,
|
||||
true,
|
||||
false
|
||||
true
|
||||
);
|
||||
|
||||
cascadeAfterReplicate( entity, persister, replicationMode, source );
|
||||
|
|
|
@ -313,8 +313,7 @@ public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener
|
|||
LockMode.NONE,
|
||||
true,
|
||||
persister,
|
||||
false,
|
||||
true // assume true, since we don't really know, and it doesn't matter
|
||||
false
|
||||
);
|
||||
|
||||
persister.afterReassociate( entity, source );
|
||||
|
|
|
@ -1697,8 +1697,9 @@ public abstract class Loader {
|
|||
final Loadable persister = (Loadable) getFactory().getEntityPersister( instanceEntityName );
|
||||
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
"Initializing object from ResultSet: {0}", MessageHelper.infoString(
|
||||
LOG.tracef(
|
||||
"Initializing object from ResultSet: %s",
|
||||
MessageHelper.infoString(
|
||||
persister,
|
||||
id,
|
||||
getFactory()
|
||||
|
@ -1706,7 +1707,7 @@ public abstract class Loader {
|
|||
);
|
||||
}
|
||||
|
||||
boolean eagerPropertyFetch = isEagerPropertyFetchEnabled( i );
|
||||
boolean fetchAllPropertiesRequested = isEagerPropertyFetchEnabled( i );
|
||||
|
||||
// add temp entry so that the next step is circular-reference
|
||||
// safe - only needed because some types don't take proper
|
||||
|
@ -1716,7 +1717,6 @@ public abstract class Loader {
|
|||
object,
|
||||
persister,
|
||||
lockMode,
|
||||
!eagerPropertyFetch,
|
||||
session
|
||||
);
|
||||
|
||||
|
@ -1731,7 +1731,7 @@ public abstract class Loader {
|
|||
object,
|
||||
rootPersister,
|
||||
cols,
|
||||
eagerPropertyFetch,
|
||||
fetchAllPropertiesRequested,
|
||||
session
|
||||
);
|
||||
|
||||
|
@ -1768,7 +1768,6 @@ public abstract class Loader {
|
|||
rowId,
|
||||
object,
|
||||
lockMode,
|
||||
!eagerPropertyFetch,
|
||||
session
|
||||
);
|
||||
|
||||
|
|
|
@ -296,7 +296,6 @@ public class EntityReferenceInitializerImpl implements EntityReferenceInitialize
|
|||
entityInstance,
|
||||
concreteEntityPersister,
|
||||
lockModeToAcquire,
|
||||
!context.getLoadPlan().areLazyAttributesForceFetched(),
|
||||
context.getSession()
|
||||
);
|
||||
|
||||
|
@ -373,7 +372,6 @@ public class EntityReferenceInitializerImpl implements EntityReferenceInitialize
|
|||
rowId,
|
||||
entityInstance,
|
||||
lockModeToAcquire,
|
||||
!context.getLoadPlan().areLazyAttributesForceFetched(),
|
||||
context.getSession()
|
||||
);
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ public class Property implements Serializable, MetaAttributable {
|
|||
private ValueGeneration valueGenerationStrategy;
|
||||
private String propertyAccessorName;
|
||||
private boolean lazy;
|
||||
private String lazyGroup;
|
||||
private boolean optional;
|
||||
private java.util.Map metaAttributes;
|
||||
private PersistentClass persistentClass;
|
||||
|
@ -258,6 +259,14 @@ public class Property implements Serializable, MetaAttributable {
|
|||
return lazy;
|
||||
}
|
||||
|
||||
public String getLazyGroup() {
|
||||
return lazyGroup;
|
||||
}
|
||||
|
||||
public void setLazyGroup(String lazyGroup) {
|
||||
this.lazyGroup = lazyGroup;
|
||||
}
|
||||
|
||||
public boolean isOptimisticLocked() {
|
||||
return optimisticLocked;
|
||||
}
|
||||
|
|
|
@ -33,8 +33,10 @@ import org.hibernate.QueryException;
|
|||
import org.hibernate.Session;
|
||||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.StaleStateException;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeDescriptor;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributesMetadata;
|
||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
|
||||
import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy;
|
||||
|
@ -65,6 +67,7 @@ import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
|||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.engine.spi.PersistenceContext.NaturalIdHelper;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.engine.spi.ValueInclusion;
|
||||
|
@ -160,8 +163,6 @@ public abstract class AbstractEntityPersister
|
|||
private final boolean hasSubselectLoadableCollections;
|
||||
protected final String rowIdName;
|
||||
|
||||
private final Set lazyProperties;
|
||||
|
||||
// The optional SQL string defined in the where attribute
|
||||
private final String sqlWhereString;
|
||||
private final String sqlWhereStringTemplate;
|
||||
|
@ -227,7 +228,7 @@ public abstract class AbstractEntityPersister
|
|||
// SQL strings
|
||||
private String sqlVersionSelectString;
|
||||
private String sqlSnapshotSelectString;
|
||||
private String sqlLazySelectString;
|
||||
private Map<String,String> sqlLazySelectStringsByFetchGroup;
|
||||
|
||||
private String sqlIdentityInsertString;
|
||||
private String sqlUpdateByRowIdString;
|
||||
|
@ -379,8 +380,8 @@ public abstract class AbstractEntityPersister
|
|||
return sqlSnapshotSelectString;
|
||||
}
|
||||
|
||||
protected String getSQLLazySelectString() {
|
||||
return sqlLazySelectString;
|
||||
protected String getSQLLazySelectString(String fetchGroup) {
|
||||
return sqlLazySelectStringsByFetchGroup.get( fetchGroup );
|
||||
}
|
||||
|
||||
protected String[] getSQLDeleteStrings() {
|
||||
|
@ -590,7 +591,6 @@ public abstract class AbstractEntityPersister
|
|||
propertyColumnInsertable = new boolean[hydrateSpan][];
|
||||
HashSet thisClassProperties = new HashSet();
|
||||
|
||||
lazyProperties = new HashSet();
|
||||
ArrayList lazyNames = new ArrayList();
|
||||
ArrayList lazyNumbers = new ArrayList();
|
||||
ArrayList lazyTypes = new ArrayList();
|
||||
|
@ -635,7 +635,6 @@ public abstract class AbstractEntityPersister
|
|||
propertyColumnAliases[i] = colAliases;
|
||||
|
||||
if ( lazyAvailable && prop.isLazy() ) {
|
||||
lazyProperties.add( prop.getName() );
|
||||
lazyNames.add( prop.getName() );
|
||||
lazyNumbers.add( i );
|
||||
lazyTypes.add( prop.getValue().getType() );
|
||||
|
@ -844,54 +843,68 @@ public abstract class AbstractEntityPersister
|
|||
Template.renderWhereStringTemplate( string, factory.getDialect(), factory.getSqlFunctionRegistry() );
|
||||
}
|
||||
|
||||
protected String generateLazySelectString() {
|
||||
|
||||
if ( !entityMetamodel.hasLazyProperties() ) {
|
||||
return null;
|
||||
protected Map<String,String> generateLazySelectStringsByFetchGroup() {
|
||||
final BytecodeEnhancementMetadata enhancementMetadata = entityMetamodel.getBytecodeEnhancementMetadata();
|
||||
if ( !enhancementMetadata.isEnhancedForLazyLoading()
|
||||
|| !enhancementMetadata.getLazyAttributesMetadata().hasLazyAttributes() ) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
HashSet tableNumbers = new HashSet();
|
||||
ArrayList columnNumbers = new ArrayList();
|
||||
ArrayList formulaNumbers = new ArrayList();
|
||||
for ( String lazyPropertyName : lazyPropertyNames ) {
|
||||
// all this only really needs to consider properties
|
||||
// of this class, not its subclasses, but since we
|
||||
// are reusing code used for sequential selects, we
|
||||
// use the subclass closure
|
||||
int propertyNumber = getSubclassPropertyIndex( lazyPropertyName );
|
||||
Map<String,String> result = new HashMap<String, String>();
|
||||
|
||||
int tableNumber = getSubclassPropertyTableNumber( propertyNumber );
|
||||
tableNumbers.add( tableNumber );
|
||||
final LazyAttributesMetadata lazyAttributesMetadata = enhancementMetadata.getLazyAttributesMetadata();
|
||||
for ( String groupName : lazyAttributesMetadata.getFetchGroupNames() ) {
|
||||
HashSet tableNumbers = new HashSet();
|
||||
ArrayList columnNumbers = new ArrayList();
|
||||
ArrayList formulaNumbers = new ArrayList();
|
||||
|
||||
int[] colNumbers = subclassPropertyColumnNumberClosure[propertyNumber];
|
||||
for ( int colNumber : colNumbers ) {
|
||||
if ( colNumber != -1 ) {
|
||||
columnNumbers.add( colNumber );
|
||||
for ( LazyAttributeDescriptor lazyAttributeDescriptor :
|
||||
lazyAttributesMetadata.getFetchGroupAttributeDescriptors( groupName ) ) {
|
||||
// all this only really needs to consider properties
|
||||
// of this class, not its subclasses, but since we
|
||||
// are reusing code used for sequential selects, we
|
||||
// use the subclass closure
|
||||
int propertyNumber = getSubclassPropertyIndex( lazyAttributeDescriptor.getName() );
|
||||
|
||||
int tableNumber = getSubclassPropertyTableNumber( propertyNumber );
|
||||
tableNumbers.add( tableNumber );
|
||||
|
||||
int[] colNumbers = subclassPropertyColumnNumberClosure[propertyNumber];
|
||||
for ( int colNumber : colNumbers ) {
|
||||
if ( colNumber != -1 ) {
|
||||
columnNumbers.add( colNumber );
|
||||
}
|
||||
}
|
||||
int[] formNumbers = subclassPropertyFormulaNumberClosure[propertyNumber];
|
||||
for ( int formNumber : formNumbers ) {
|
||||
if ( formNumber != -1 ) {
|
||||
formulaNumbers.add( formNumber );
|
||||
}
|
||||
}
|
||||
}
|
||||
int[] formNumbers = subclassPropertyFormulaNumberClosure[propertyNumber];
|
||||
for ( int formNumber : formNumbers ) {
|
||||
if ( formNumber != -1 ) {
|
||||
formulaNumbers.add( formNumber );
|
||||
}
|
||||
|
||||
if ( columnNumbers.size() == 0 && formulaNumbers.size() == 0 ) {
|
||||
// only one-to-one is lazy fetched
|
||||
continue;
|
||||
}
|
||||
|
||||
result.put(
|
||||
groupName,
|
||||
renderSelect(
|
||||
ArrayHelper.toIntArray( tableNumbers ),
|
||||
ArrayHelper.toIntArray( columnNumbers ),
|
||||
ArrayHelper.toIntArray( formulaNumbers )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( columnNumbers.size() == 0 && formulaNumbers.size() == 0 ) {
|
||||
// only one-to-one is lazy fetched
|
||||
return null;
|
||||
}
|
||||
|
||||
return renderSelect(
|
||||
ArrayHelper.toIntArray( tableNumbers ),
|
||||
ArrayHelper.toIntArray( columnNumbers ),
|
||||
ArrayHelper.toIntArray( formulaNumbers )
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session) {
|
||||
final EntityEntry entry = session.getPersistenceContext().getEntry( entity );
|
||||
final InterceptorImplementor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
|
||||
assert interceptor != null : "Expecting bytecode interceptor to be non-null";
|
||||
|
||||
if ( hasCollections() ) {
|
||||
final Type type = getPropertyType( fieldName );
|
||||
|
@ -919,6 +932,7 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
// Initialize it
|
||||
session.initializeCollection( collection, false );
|
||||
interceptor.attributeInitialized( fieldName );
|
||||
|
||||
if ( collectionType.isArrayType() ) {
|
||||
session.getPersistenceContext().addCollectionHolder( collection );
|
||||
|
@ -944,16 +958,17 @@ public abstract class AbstractEntityPersister
|
|||
);
|
||||
}
|
||||
|
||||
if ( session.getCacheMode().isGetEnabled() && hasCache() ) {
|
||||
if ( session.getCacheMode().isGetEnabled() && hasCache() && isLazyPropertiesCacheable() ) {
|
||||
final EntityRegionAccessStrategy cache = getCacheAccessStrategy();
|
||||
final Object cacheKey = cache.generateCacheKey(id, this, session.getFactory(), session.getTenantIdentifier() );
|
||||
final Object ce = CacheHelper.fromSharedCache( session, cacheKey, cache );
|
||||
if ( ce != null ) {
|
||||
final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure( ce, factory );
|
||||
if ( !cacheEntry.areLazyPropertiesUnfetched() ) {
|
||||
//note early exit here:
|
||||
return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry );
|
||||
}
|
||||
final Object initializedValue = initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry );
|
||||
interceptor.attributeInitialized( fieldName );
|
||||
|
||||
// NOTE EARLY EXIT!!!
|
||||
return initializedValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -993,14 +1008,26 @@ public abstract class AbstractEntityPersister
|
|||
throw new AssertionFailure( "no lazy properties" );
|
||||
}
|
||||
|
||||
final InterceptorImplementor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
|
||||
assert interceptor != null : "Expecting bytecode interceptor to be non-null";
|
||||
|
||||
LOG.trace( "Initializing lazy properties from datastore" );
|
||||
|
||||
try {
|
||||
final String fetchGroup = getEntityMetamodel().getBytecodeEnhancementMetadata()
|
||||
.getLazyAttributesMetadata()
|
||||
.getFetchGroupName( fieldName );
|
||||
final List<LazyAttributeDescriptor> fetchGroupAttributeDescriptors = getEntityMetamodel().getBytecodeEnhancementMetadata()
|
||||
.getLazyAttributesMetadata()
|
||||
.getFetchGroupAttributeDescriptors( fetchGroup );
|
||||
|
||||
final Set<String> initializedLazyAttributeNames = interceptor.getInitializedLazyAttributeNames();
|
||||
|
||||
final String lazySelect = getSQLLazySelectString( fetchGroup );
|
||||
|
||||
try {
|
||||
Object result = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
final String lazySelect = getSQLLazySelectString();
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
if ( lazySelect != null ) {
|
||||
|
@ -1015,16 +1042,31 @@ public abstract class AbstractEntityPersister
|
|||
rs.next();
|
||||
}
|
||||
final Object[] snapshot = entry.getLoadedState();
|
||||
for ( int j = 0; j < lazyPropertyNames.length; j++ ) {
|
||||
Object propValue = lazyPropertyTypes[j].nullSafeGet(
|
||||
for ( LazyAttributeDescriptor fetchGroupAttributeDescriptor : fetchGroupAttributeDescriptors ) {
|
||||
final boolean previousInitialized = initializedLazyAttributeNames.contains( fetchGroupAttributeDescriptor.getName() );
|
||||
final Object loadedValue = fetchGroupAttributeDescriptor.getType().nullSafeGet(
|
||||
rs,
|
||||
lazyPropertyColumnAliases[j],
|
||||
lazyPropertyColumnAliases[fetchGroupAttributeDescriptor.getLazyIndex()],
|
||||
session,
|
||||
entity
|
||||
);
|
||||
if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) {
|
||||
result = propValue;
|
||||
final boolean set = initializeLazyProperty(
|
||||
fieldName,
|
||||
entity,
|
||||
session,
|
||||
snapshot,
|
||||
fetchGroupAttributeDescriptor.getLazyIndex(),
|
||||
loadedValue
|
||||
);
|
||||
if ( previousInitialized ) {
|
||||
// its already been initialized (e.g. by a write) so we don't want to overwrite
|
||||
continue;
|
||||
}
|
||||
if ( set ) {
|
||||
result = loadedValue;
|
||||
interceptor.attributeInitialized( fetchGroupAttributeDescriptor.getName() );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
@ -1048,9 +1090,8 @@ public abstract class AbstractEntityPersister
|
|||
catch (SQLException sqle) {
|
||||
throw getFactory().getSQLExceptionHelper().convert(
|
||||
sqle,
|
||||
"could not initialize lazy properties: " +
|
||||
MessageHelper.infoString( this, id, getFactory() ),
|
||||
getSQLLazySelectString()
|
||||
"could not initialize lazy properties: " + MessageHelper.infoString( this, id, getFactory() ),
|
||||
lazySelect
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1060,8 +1101,7 @@ public abstract class AbstractEntityPersister
|
|||
final Object entity,
|
||||
final SessionImplementor session,
|
||||
final EntityEntry entry,
|
||||
final CacheEntry cacheEntry
|
||||
) {
|
||||
final CacheEntry cacheEntry) {
|
||||
|
||||
LOG.trace( "Initializing lazy properties from second-level cache" );
|
||||
|
||||
|
@ -1109,10 +1149,6 @@ public abstract class AbstractEntityPersister
|
|||
return getPropertySpaces();
|
||||
}
|
||||
|
||||
protected Set getLazyProperties() {
|
||||
return lazyProperties;
|
||||
}
|
||||
|
||||
public boolean isBatchLoadable() {
|
||||
return batchSize > 1;
|
||||
}
|
||||
|
@ -3475,8 +3511,8 @@ public abstract class AbstractEntityPersister
|
|||
protected void logStaticSQL() {
|
||||
if ( LOG.isDebugEnabled() ) {
|
||||
LOG.debugf( "Static SQL for entity: %s", getEntityName() );
|
||||
if ( sqlLazySelectString != null ) {
|
||||
LOG.debugf( " Lazy select: %s", sqlLazySelectString );
|
||||
for ( Map.Entry<String, String> entry : sqlLazySelectStringsByFetchGroup.entrySet() ) {
|
||||
LOG.debugf( " Lazy select (%s) : %s", entry.getKey(), entry.getValue() );
|
||||
}
|
||||
if ( sqlVersionSelectString != null ) {
|
||||
LOG.debugf( " Version select: %s", sqlVersionSelectString );
|
||||
|
@ -3815,7 +3851,7 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
//select SQL
|
||||
sqlSnapshotSelectString = generateSnapshotSelectString();
|
||||
sqlLazySelectString = generateLazySelectString();
|
||||
sqlLazySelectStringsByFetchGroup = generateLazySelectStringsByFetchGroup();
|
||||
sqlVersionSelectString = generateSelectVersionString();
|
||||
if ( hasInsertGeneratedProperties() ) {
|
||||
sqlInsertGeneratedValuesSelectString = generateInsertGeneratedValuesSelectString();
|
||||
|
@ -4244,11 +4280,7 @@ public abstract class AbstractEntityPersister
|
|||
if ( getEntityMetamodel().getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
|
||||
LazyAttributeLoadingInterceptor interceptor = getEntityMetamodel().getBytecodeEnhancementMetadata().extractInterceptor( entity );
|
||||
if ( interceptor == null ) {
|
||||
getEntityMetamodel().getBytecodeEnhancementMetadata().injectInterceptor(
|
||||
entity,
|
||||
null,
|
||||
session
|
||||
);
|
||||
getEntityMetamodel().getBytecodeEnhancementMetadata().injectInterceptor( entity, session );
|
||||
}
|
||||
else {
|
||||
interceptor.setSession( session );
|
||||
|
@ -4483,8 +4515,9 @@ public abstract class AbstractEntityPersister
|
|||
return isVersioned() && getPropertyInsertability()[getVersionProperty()];
|
||||
}
|
||||
|
||||
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
|
||||
getEntityTuplizer().afterInitialize( entity, lazyPropertiesAreUnfetched, session );
|
||||
@Override
|
||||
public void afterInitialize(Object entity, SessionImplementor session) {
|
||||
getEntityTuplizer().afterInitialize( entity, session );
|
||||
}
|
||||
|
||||
public String[] getPropertyNames() {
|
||||
|
@ -4609,7 +4642,7 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
@Override
|
||||
public boolean hasUninitializedLazyProperties(Object object) {
|
||||
return getEntityTuplizer().hasUninitializedLazyProperties( object );
|
||||
return entityMetamodel.getBytecodeEnhancementMetadata().hasUnFetchedAttributes( object );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5143,7 +5176,6 @@ public abstract class AbstractEntityPersister
|
|||
return new StandardCacheEntryImpl(
|
||||
state,
|
||||
persister,
|
||||
persister.hasUninitializedLazyProperties( entity ),
|
||||
version,
|
||||
session,
|
||||
entity
|
||||
|
@ -5188,7 +5220,6 @@ public abstract class AbstractEntityPersister
|
|||
return new StandardCacheEntryImpl(
|
||||
state,
|
||||
persister,
|
||||
persister.hasUninitializedLazyProperties( entity ),
|
||||
version,
|
||||
session,
|
||||
entity
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.persister.entity;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -589,7 +590,7 @@ public interface EntityPersister extends OptimisticCacheSource, EntityDefinition
|
|||
/**
|
||||
* Called just after the entities properties have been initialized
|
||||
*/
|
||||
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session);
|
||||
void afterInitialize(Object entity, SessionImplementor session);
|
||||
|
||||
/**
|
||||
* Called just after the entity has been reassociated with the session
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.hibernate.PropertyNotFoundException;
|
|||
import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.property.access.spi.EnhancedGetterMethodImpl;
|
||||
import org.hibernate.property.access.spi.EnhancedSetterMethodImpl;
|
||||
import org.hibernate.property.access.spi.EnhancedSetterImpl;
|
||||
import org.hibernate.property.access.spi.Getter;
|
||||
import org.hibernate.property.access.spi.GetterFieldImpl;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
|
@ -32,7 +32,6 @@ import org.hibernate.property.access.spi.SetterFieldImpl;
|
|||
*/
|
||||
public class PropertyAccessEnhancedImpl implements PropertyAccess {
|
||||
private final PropertyAccessStrategyEnhancedImpl strategy;
|
||||
|
||||
private final Getter getter;
|
||||
private final Setter setter;
|
||||
|
||||
|
@ -42,42 +41,50 @@ public class PropertyAccessEnhancedImpl implements PropertyAccess {
|
|||
String propertyName) {
|
||||
this.strategy = strategy;
|
||||
|
||||
// field represents the enhanced field on the entity
|
||||
final Field field = fieldOrNull( containerJavaType, propertyName );
|
||||
final Method getterMethod = getterMethodOrNull( containerJavaType, propertyName );
|
||||
|
||||
final Class propertyJavaType;
|
||||
|
||||
// need one of field or getterMethod to be non-null
|
||||
if ( field == null && getterMethod == null ) {
|
||||
String msg = String.format( "Could not locate field nor getter method for property named [%s#%s]",
|
||||
containerJavaType.getName(),
|
||||
propertyName );
|
||||
throw new PropertyAccessBuildingException( msg );
|
||||
}
|
||||
else if ( field != null ) {
|
||||
propertyJavaType = field.getType();
|
||||
this.getter = resolveGetterForField( containerJavaType, propertyName, field );
|
||||
}
|
||||
else {
|
||||
propertyJavaType = getterMethod.getReturnType();
|
||||
this.getter = new EnhancedGetterMethodImpl( containerJavaType, propertyName, getterMethod );
|
||||
if ( field == null ) {
|
||||
throw new PropertyAccessBuildingException(
|
||||
String.format(
|
||||
"Could not locate field for property [%s] on bytecode-enhanced Class [%s]",
|
||||
propertyName,
|
||||
containerJavaType.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
final Method setterMethod = setterMethodOrNull( containerJavaType, propertyName, propertyJavaType );
|
||||
|
||||
// need one of field or setterMethod to be non-null
|
||||
if ( field == null && setterMethod == null ) {
|
||||
String msg = String.format( "Could not locate field nor getter method for property named [%s#%s]",
|
||||
containerJavaType.getName(),
|
||||
propertyName );
|
||||
throw new PropertyAccessBuildingException( msg );
|
||||
}
|
||||
else if ( field != null ) {
|
||||
this.setter = resolveSetterForField( containerJavaType, propertyName, field );
|
||||
}
|
||||
else {
|
||||
this.setter = new EnhancedSetterMethodImpl( containerJavaType, propertyName, setterMethod );
|
||||
}
|
||||
this.getter = new GetterFieldImpl( containerJavaType, propertyName, field );
|
||||
this.setter = resolveEnhancedSetterForField( containerJavaType, propertyName, field );
|
||||
//
|
||||
// // need one of field or getterMethod to be non-null
|
||||
// if ( field == null && getterMethod == null ) {
|
||||
// String msg = ;
|
||||
// throw new PropertyAccessBuildingException( msg );
|
||||
// }
|
||||
// else if ( field != null ) {
|
||||
// propertyJavaType = field.getType();
|
||||
// this.getter = resolveGetterForField( containerJavaType, propertyName, field );
|
||||
// }
|
||||
// else {
|
||||
// propertyJavaType = getterMethod.getReturnType();
|
||||
// this.getter = new EnhancedGetterMethodImpl( containerJavaType, propertyName, field, getterMethod );
|
||||
// }
|
||||
//
|
||||
// final Method setterMethod = setterMethodOrNull( containerJavaType, propertyName, propertyJavaType );
|
||||
//
|
||||
// // need one of field or setterMethod to be non-null
|
||||
// if ( field == null && setterMethod == null ) {
|
||||
// String msg = String.format( "Could not locate field nor getter method for property named [%s#%s]",
|
||||
// containerJavaType.getName(),
|
||||
// propertyName );
|
||||
// throw new PropertyAccessBuildingException( msg );
|
||||
// }
|
||||
// else if ( field != null ) {
|
||||
// this.setter = resolveSetterForField( containerJavaType, propertyName, field );
|
||||
// }
|
||||
// else {
|
||||
// this.setter = new EnhancedSetterImpl( containerJavaType, propertyName, setterMethod );
|
||||
// }
|
||||
}
|
||||
|
||||
private static Field fieldOrNull(Class containerJavaType, String propertyName) {
|
||||
|
@ -107,27 +114,26 @@ public class PropertyAccessEnhancedImpl implements PropertyAccess {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// private static Getter resolveGetterForField(Class<?> containerClass, String propertyName, Field field) {
|
||||
// try {
|
||||
// String enhancedGetterName = EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + propertyName;
|
||||
// Method enhancedGetter = containerClass.getDeclaredMethod( enhancedGetterName );
|
||||
// enhancedGetter.setAccessible( true );
|
||||
// return new EnhancedGetterMethodImpl( containerClass, propertyName, field, enhancedGetter );
|
||||
// }
|
||||
// catch (NoSuchMethodException e) {
|
||||
// // enhancedGetter = null --- field not enhanced: fallback to reflection using the field
|
||||
// return new GetterFieldImpl( containerClass, propertyName, field );
|
||||
// }
|
||||
// }
|
||||
|
||||
private static Getter resolveGetterForField(Class<?> containerClass, String propertyName, Field field) {
|
||||
try {
|
||||
String enhancedGetterName = EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + propertyName;
|
||||
Method enhancedGetter = containerClass.getDeclaredMethod( enhancedGetterName );
|
||||
enhancedGetter.setAccessible( true );
|
||||
return new EnhancedGetterMethodImpl( containerClass, propertyName, enhancedGetter );
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
// enhancedGetter = null --- field not enhanced: fallback to reflection using the field
|
||||
return new GetterFieldImpl( containerClass, propertyName, field );
|
||||
}
|
||||
}
|
||||
|
||||
private static Setter resolveSetterForField(Class<?> containerClass, String propertyName, Field field) {
|
||||
private static Setter resolveEnhancedSetterForField(Class<?> containerClass, String propertyName, Field field) {
|
||||
try {
|
||||
String enhancedSetterName = EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + propertyName;
|
||||
Method enhancedSetter = containerClass.getDeclaredMethod( enhancedSetterName, field.getType() );
|
||||
enhancedSetter.setAccessible( true );
|
||||
return new EnhancedSetterMethodImpl( containerClass, propertyName, enhancedSetter );
|
||||
return new EnhancedSetterImpl( containerClass, propertyName, enhancedSetter );
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
// enhancedSetter = null --- field not enhanced: fallback to reflection using the field
|
||||
|
|
|
@ -34,11 +34,13 @@ public class PropertyAccessStrategyResolverStandardImpl implements PropertyAcces
|
|||
String explicitAccessStrategyName,
|
||||
EntityMode entityMode) {
|
||||
|
||||
if ( ( BuiltInPropertyAccessStrategies.BASIC.getExternalName().equals( explicitAccessStrategyName ) ||
|
||||
BuiltInPropertyAccessStrategies.FIELD.getExternalName().equals( explicitAccessStrategyName ) ||
|
||||
BuiltInPropertyAccessStrategies.MIXED.getExternalName().equals( explicitAccessStrategyName ) ) &&
|
||||
Managed.class.isAssignableFrom( containerClass ) ) {
|
||||
return PropertyAccessStrategyEnhancedImpl.INSTANCE;
|
||||
if ( BuiltInPropertyAccessStrategies.BASIC.getExternalName().equals( explicitAccessStrategyName )
|
||||
|| BuiltInPropertyAccessStrategies.FIELD.getExternalName().equals( explicitAccessStrategyName )
|
||||
|| BuiltInPropertyAccessStrategies.MIXED.getExternalName().equals( explicitAccessStrategyName ) ) {
|
||||
if ( Managed.class.isAssignableFrom( containerClass ) ) {
|
||||
// PROPERTY (BASIC) and MIXED are not valid for bytecode enhanced entities...
|
||||
return PropertyAccessStrategyEnhancedImpl.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( StringHelper.isNotEmpty( explicitAccessStrategyName ) ) {
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.property.access.spi;
|
|||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -30,44 +31,50 @@ public class EnhancedGetterMethodImpl implements Getter {
|
|||
|
||||
private final Class containerClass;
|
||||
private final String propertyName;
|
||||
private final Field field;
|
||||
private final Method getterMethod;
|
||||
|
||||
public EnhancedGetterMethodImpl(Class containerClass, String propertyName, Method getterMethod) {
|
||||
public EnhancedGetterMethodImpl(
|
||||
Class containerClass,
|
||||
String propertyName,
|
||||
Field field,
|
||||
Method getterMethod) {
|
||||
this.containerClass = containerClass;
|
||||
this.propertyName = propertyName;
|
||||
this.field = field;
|
||||
this.getterMethod = getterMethod;
|
||||
}
|
||||
|
||||
private boolean isAttributeLoaded(Object owner) {
|
||||
if ( owner instanceof PersistentAttributeInterceptable ) {
|
||||
PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) owner ).$$_hibernate_getInterceptor();
|
||||
if ( interceptor != null && interceptor instanceof LazyAttributeLoadingInterceptor ) {
|
||||
return ( (LazyAttributeLoadingInterceptor) interceptor ).isAttributeLoaded( propertyName );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// private boolean isAttributeLoaded(Object owner) {
|
||||
// if ( owner instanceof PersistentAttributeInterceptable ) {
|
||||
// PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) owner ).$$_hibernate_getInterceptor();
|
||||
// if ( interceptor != null && interceptor instanceof LazyAttributeLoadingInterceptor ) {
|
||||
// return ( (LazyAttributeLoadingInterceptor) interceptor ).isAttributeLoaded( propertyName );
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public Object get(Object owner) {
|
||||
try {
|
||||
return field.get( owner );
|
||||
|
||||
// We don't want to trigger lazy loading of byte code enhanced attributes
|
||||
if ( isAttributeLoaded( owner ) ) {
|
||||
return getterMethod.invoke( owner );
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
catch (InvocationTargetException ite) {
|
||||
throw new PropertyAccessException(
|
||||
ite,
|
||||
"Exception occurred inside",
|
||||
false,
|
||||
containerClass,
|
||||
propertyName
|
||||
);
|
||||
// // We don't want to trigger lazy loading of byte code enhanced attributes
|
||||
// if ( isAttributeLoaded( owner ) ) {
|
||||
// return getterMethod.invoke( owner );
|
||||
// }
|
||||
// return null;
|
||||
}
|
||||
// catch (InvocationTargetException ite) {
|
||||
// throw new PropertyAccessException(
|
||||
// ite,
|
||||
// "Exception occurred inside",
|
||||
// false,
|
||||
// containerClass,
|
||||
// propertyName
|
||||
// );
|
||||
// }
|
||||
catch (IllegalAccessException iae) {
|
||||
throw new PropertyAccessException(
|
||||
iae,
|
||||
|
@ -134,7 +141,7 @@ public class EnhancedGetterMethodImpl implements Getter {
|
|||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return new EnhancedGetterMethodImpl( containerClass, propertyName, resolveMethod() );
|
||||
return new EnhancedGetterMethodImpl( containerClass, propertyName, resolveField(), resolveMethod() );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -148,5 +155,17 @@ public class EnhancedGetterMethodImpl implements Getter {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Field resolveField() {
|
||||
try {
|
||||
return declaringClass.getDeclaredField( propertyName );
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
throw new PropertyAccessSerializationException(
|
||||
"Unable to resolve field on deserialization : " + declaringClass.getName() + "#" + propertyName
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,15 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||
|
||||
/**
|
||||
* A specialized Setter implementation for handling setting values into
|
||||
* a into a bytecode-enhanced Class. The reason we need specialized handling
|
||||
* is to render the fact that the
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Luis Barreiro
|
||||
*/
|
||||
public class EnhancedSetterMethodImpl implements Setter {
|
||||
private static final CoreMessageLogger LOG = messageLogger( EnhancedSetterMethodImpl.class );
|
||||
public class EnhancedSetterImpl implements Setter {
|
||||
private static final CoreMessageLogger LOG = messageLogger( EnhancedSetterImpl.class );
|
||||
|
||||
private final Class containerClass;
|
||||
private final String propertyName;
|
||||
|
@ -31,7 +36,7 @@ public class EnhancedSetterMethodImpl implements Setter {
|
|||
|
||||
private final boolean isPrimitive;
|
||||
|
||||
public EnhancedSetterMethodImpl(Class containerClass, String propertyName, Method setterMethod) {
|
||||
public EnhancedSetterImpl(Class containerClass, String propertyName, Method setterMethod) {
|
||||
this.containerClass = containerClass;
|
||||
this.propertyName = propertyName;
|
||||
this.setterMethod = setterMethod;
|
||||
|
@ -153,7 +158,7 @@ public class EnhancedSetterMethodImpl implements Setter {
|
|||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return new EnhancedSetterMethodImpl( containerClass, propertyName, resolveMethod() );
|
||||
return new EnhancedSetterImpl( containerClass, propertyName, resolveMethod() );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
|
@ -13,34 +13,47 @@ import java.lang.reflect.Constructor;
|
|||
import org.hibernate.InstantiationException;
|
||||
import org.hibernate.PropertyNotFoundException;
|
||||
import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Defines a POJO-based instantiator for use from the tuplizers.
|
||||
*/
|
||||
public class PojoInstantiator implements Instantiator, Serializable {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, PojoInstantiator.class.getName());
|
||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoInstantiator.class.getName() );
|
||||
|
||||
private transient Constructor constructor;
|
||||
|
||||
private final Class mappedClass;
|
||||
private final transient ReflectionOptimizer.InstantiationOptimizer optimizer;
|
||||
private final boolean embeddedIdentifier;
|
||||
private final Class proxyInterface;
|
||||
private final boolean isAbstract;
|
||||
|
||||
public PojoInstantiator(
|
||||
Class mappedClass,
|
||||
ReflectionOptimizer.InstantiationOptimizer optimizer,
|
||||
boolean embeddedIdentifier) {
|
||||
this.mappedClass = mappedClass;
|
||||
this.optimizer = optimizer;
|
||||
this.embeddedIdentifier = embeddedIdentifier;
|
||||
this.isAbstract = ReflectHelper.isAbstractClass( mappedClass );
|
||||
|
||||
try {
|
||||
constructor = ReflectHelper.getDefaultConstructor(mappedClass);
|
||||
}
|
||||
catch ( PropertyNotFoundException pnfe ) {
|
||||
LOG.noDefaultConstructor( mappedClass.getName() );
|
||||
constructor = null;
|
||||
}
|
||||
}
|
||||
|
||||
public PojoInstantiator(Component component, ReflectionOptimizer.InstantiationOptimizer optimizer) {
|
||||
this.mappedClass = component.getComponentClass();
|
||||
this.isAbstract = ReflectHelper.isAbstractClass( mappedClass );
|
||||
this.optimizer = optimizer;
|
||||
|
||||
this.proxyInterface = null;
|
||||
this.embeddedIdentifier = false;
|
||||
|
||||
try {
|
||||
|
@ -52,22 +65,6 @@ public class PojoInstantiator implements Instantiator, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public PojoInstantiator(PersistentClass persistentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) {
|
||||
this.mappedClass = persistentClass.getMappedClass();
|
||||
this.isAbstract = ReflectHelper.isAbstractClass( mappedClass );
|
||||
this.proxyInterface = persistentClass.getProxyInterface();
|
||||
this.embeddedIdentifier = persistentClass.hasEmbeddedIdentifier();
|
||||
this.optimizer = optimizer;
|
||||
|
||||
try {
|
||||
constructor = ReflectHelper.getDefaultConstructor( mappedClass );
|
||||
}
|
||||
catch ( PropertyNotFoundException pnfe ) {
|
||||
LOG.noDefaultConstructor(mappedClass.getName());
|
||||
constructor = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream stream) throws ClassNotFoundException, IOException {
|
||||
stream.defaultReadObject();
|
||||
constructor = ReflectHelper.getDefaultConstructor( mappedClass );
|
||||
|
@ -85,7 +82,7 @@ public class PojoInstantiator implements Instantiator, Serializable {
|
|||
}
|
||||
else {
|
||||
try {
|
||||
return constructor.newInstance( (Object[]) null );
|
||||
return applyInterception( constructor.newInstance( (Object[]) null ) );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new InstantiationException( "Could not instantiate entity: ", mappedClass, e );
|
||||
|
@ -93,6 +90,10 @@ public class PojoInstantiator implements Instantiator, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
protected Object applyInterception(Object entity) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Object instantiate(Serializable id) {
|
||||
final boolean useEmbeddedIdentifierInstanceAsEntity = embeddedIdentifier &&
|
||||
id != null &&
|
||||
|
@ -101,7 +102,6 @@ public class PojoInstantiator implements Instantiator, Serializable {
|
|||
}
|
||||
|
||||
public boolean isInstance(Object object) {
|
||||
return mappedClass.isInstance(object) ||
|
||||
( proxyInterface!=null && proxyInterface.isInstance(object) ); //this one needed only for guessEntityMode()
|
||||
return mappedClass.isInstance( object );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
*
|
||||
* @return An appropriate Instantiator instance.
|
||||
*/
|
||||
protected abstract Instantiator buildInstantiator(PersistentClass mappingInfo);
|
||||
protected abstract Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass mappingInfo);
|
||||
|
||||
/**
|
||||
* Build an appropriate ProxyFactory for the given mapped entity.
|
||||
|
@ -151,7 +151,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
}
|
||||
hasCustomAccessors = foundCustomAccessor;
|
||||
|
||||
instantiator = buildInstantiator( mappingInfo );
|
||||
instantiator = buildInstantiator( entityMetamodel, mappingInfo );
|
||||
|
||||
if ( entityMetamodel.isLazy() && !entityMetamodel.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
|
||||
proxyFactory = buildProxyFactory( mappingInfo, idGetter, idSetter );
|
||||
|
@ -486,7 +486,11 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
}
|
||||
|
||||
protected boolean shouldGetAllProperties(Object entity) {
|
||||
return !hasUninitializedLazyProperties( entity );
|
||||
if ( !getEntityMetamodel().getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !getEntityMetamodel().getBytecodeEnhancementMetadata().hasUnFetchedAttributes( entity );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -641,13 +645,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUninitializedLazyProperties(Object entity) {
|
||||
// the default is to simply not lazy fetch properties for now...
|
||||
return false;
|
||||
public void afterInitialize(Object entity, SessionImplementor session) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,50 +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>.
|
||||
*/
|
||||
package org.hibernate.tuple.entity;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||
import org.hibernate.bytecode.spi.NotInstrumentedException;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BytecodeEnhancementMetadataNonEnhancedPojoImpl implements BytecodeEnhancementMetadata {
|
||||
private final Class entityClass;
|
||||
private final String errorMsg;
|
||||
|
||||
public BytecodeEnhancementMetadataNonEnhancedPojoImpl(Class entityClass) {
|
||||
this.entityClass = entityClass;
|
||||
this.errorMsg = "Entity class [" + entityClass.getName() + "] is not enhanced";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityName() {
|
||||
return entityClass.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnhancedForLazyLoading() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyAttributeLoadingInterceptor injectInterceptor(
|
||||
Object entity,
|
||||
Set<String> uninitializedFieldNames,
|
||||
SessionImplementor session) throws NotInstrumentedException {
|
||||
throw new NotInstrumentedException( errorMsg );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyAttributeLoadingInterceptor extractInterceptor(Object entity) throws NotInstrumentedException {
|
||||
throw new NotInstrumentedException( errorMsg );
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ package org.hibernate.tuple.entity;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributesMetadata;
|
||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||
import org.hibernate.bytecode.spi.NotInstrumentedException;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
@ -18,10 +19,12 @@ import org.hibernate.engine.spi.SessionImplementor;
|
|||
*/
|
||||
public class BytecodeEnhancementMetadataNonPojoImpl implements BytecodeEnhancementMetadata {
|
||||
private final String entityName;
|
||||
private final LazyAttributesMetadata lazyAttributesMetadata;
|
||||
private final String errorMsg;
|
||||
|
||||
public BytecodeEnhancementMetadataNonPojoImpl(String entityName) {
|
||||
this.entityName = entityName;
|
||||
this.lazyAttributesMetadata = LazyAttributesMetadata.nonEnhanced( entityName );
|
||||
this.errorMsg = "Entity [" + entityName + "] is non-pojo, and therefore not instrumented";
|
||||
}
|
||||
|
||||
|
@ -35,10 +38,14 @@ public class BytecodeEnhancementMetadataNonPojoImpl implements BytecodeEnhanceme
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyAttributesMetadata getLazyAttributesMetadata() {
|
||||
return lazyAttributesMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyAttributeLoadingInterceptor injectInterceptor(
|
||||
Object entity,
|
||||
Set<String> uninitializedFieldNames,
|
||||
SessionImplementor session) throws NotInstrumentedException {
|
||||
throw new NotInstrumentedException( errorMsg );
|
||||
}
|
||||
|
@ -47,4 +54,9 @@ public class BytecodeEnhancementMetadataNonPojoImpl implements BytecodeEnhanceme
|
|||
public LazyAttributeLoadingInterceptor extractInterceptor(Object entity) throws NotInstrumentedException {
|
||||
throw new NotInstrumentedException( errorMsg );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnFetchedAttributes(Object entity) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,27 +9,52 @@ package org.hibernate.tuple.entity;
|
|||
import java.util.Set;
|
||||
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributesMetadata;
|
||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||
import org.hibernate.bytecode.spi.NotInstrumentedException;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BytecodeEnhancementMetadataPojoImpl implements BytecodeEnhancementMetadata {
|
||||
public static BytecodeEnhancementMetadata from(PersistentClass persistentClass) {
|
||||
final Class mappedClass = persistentClass.getMappedClass();
|
||||
final boolean enhancedForLazyLoading = PersistentAttributeInterceptable.class.isAssignableFrom( mappedClass );
|
||||
final LazyAttributesMetadata lazyAttributesMetadata = enhancedForLazyLoading
|
||||
? LazyAttributesMetadata.from( persistentClass )
|
||||
: LazyAttributesMetadata.nonEnhanced( persistentClass.getEntityName() );
|
||||
|
||||
return new BytecodeEnhancementMetadataPojoImpl(
|
||||
persistentClass.getEntityName(),
|
||||
mappedClass,
|
||||
enhancedForLazyLoading,
|
||||
lazyAttributesMetadata
|
||||
);
|
||||
}
|
||||
|
||||
private final String entityName;
|
||||
private final Class entityClass;
|
||||
private final boolean enhancedForLazyLoading;
|
||||
private final LazyAttributesMetadata lazyAttributesMetadata;
|
||||
|
||||
public BytecodeEnhancementMetadataPojoImpl(Class entityClass) {
|
||||
public BytecodeEnhancementMetadataPojoImpl(
|
||||
String entityName,
|
||||
Class entityClass,
|
||||
boolean enhancedForLazyLoading,
|
||||
LazyAttributesMetadata lazyAttributesMetadata) {
|
||||
this.entityName = entityName;
|
||||
this.entityClass = entityClass;
|
||||
this.enhancedForLazyLoading = PersistentAttributeInterceptable.class.isAssignableFrom( entityClass );
|
||||
this.enhancedForLazyLoading = enhancedForLazyLoading;
|
||||
this.lazyAttributesMetadata = lazyAttributesMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityName() {
|
||||
return entityClass.getName();
|
||||
return entityName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,6 +62,19 @@ public class BytecodeEnhancementMetadataPojoImpl implements BytecodeEnhancementM
|
|||
return enhancedForLazyLoading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyAttributesMetadata getLazyAttributesMetadata() {
|
||||
return lazyAttributesMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnFetchedAttributes(Object entity) {
|
||||
LazyAttributeLoadingInterceptor interceptor = isEnhancedForLazyLoading()
|
||||
? extractInterceptor( entity )
|
||||
: null;
|
||||
return interceptor != null && interceptor.hasAnyUninitializedAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyAttributeLoadingInterceptor extractInterceptor(Object entity) throws NotInstrumentedException {
|
||||
if ( !enhancedForLazyLoading ) {
|
||||
|
@ -62,10 +100,7 @@ public class BytecodeEnhancementMetadataPojoImpl implements BytecodeEnhancementM
|
|||
}
|
||||
|
||||
@Override
|
||||
public LazyAttributeLoadingInterceptor injectInterceptor(
|
||||
Object entity,
|
||||
Set<String> uninitializedFieldNames,
|
||||
SessionImplementor session) throws NotInstrumentedException {
|
||||
public LazyAttributeLoadingInterceptor injectInterceptor(Object entity, SessionImplementor session) {
|
||||
if ( !enhancedForLazyLoading ) {
|
||||
throw new NotInstrumentedException( "Entity class [" + entityClass.getName() + "] is not enhanced for lazy loading" );
|
||||
}
|
||||
|
@ -80,7 +115,11 @@ public class BytecodeEnhancementMetadataPojoImpl implements BytecodeEnhancementM
|
|||
);
|
||||
}
|
||||
|
||||
final LazyAttributeLoadingInterceptor interceptor = new LazyAttributeLoadingInterceptor( session, uninitializedFieldNames, getEntityName() );
|
||||
final LazyAttributeLoadingInterceptor interceptor = new LazyAttributeLoadingInterceptor(
|
||||
getEntityName(),
|
||||
lazyAttributesMetadata.getLazyAttributeNames(),
|
||||
session
|
||||
);
|
||||
( (PersistentAttributeInterceptable) entity ).$$_hibernate_setInterceptor( interceptor );
|
||||
return interceptor;
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@ import org.hibernate.internal.CoreLogging;
|
|||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.property.access.spi.Getter;
|
||||
import org.hibernate.property.access.spi.Setter;
|
||||
import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl;
|
||||
import org.hibernate.property.access.spi.Getter;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.property.access.spi.Setter;
|
||||
import org.hibernate.proxy.ProxyFactory;
|
||||
import org.hibernate.proxy.map.MapProxyFactory;
|
||||
import org.hibernate.tuple.DynamicMapInstantiator;
|
||||
|
@ -63,7 +63,7 @@ public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Instantiator buildInstantiator(PersistentClass mappingInfo) {
|
||||
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) {
|
||||
return new DynamicMapInstantiator( mappingInfo );
|
||||
}
|
||||
|
||||
|
@ -99,11 +99,6 @@ public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
|
|||
return Map.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInstrumented() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityNameResolver[] getEntityNameResolvers() {
|
||||
return new EntityNameResolver[] {BasicEntityNameResolver.INSTANCE};
|
||||
|
|
|
@ -143,7 +143,7 @@ public class EntityMetamodel implements Serializable {
|
|||
versioned = persistentClass.isVersioned();
|
||||
|
||||
if ( persistentClass.hasPojoRepresentation() ) {
|
||||
bytecodeEnhancementMetadata = new BytecodeEnhancementMetadataPojoImpl( persistentClass.getMappedClass() );
|
||||
bytecodeEnhancementMetadata = BytecodeEnhancementMetadataPojoImpl.from( persistentClass );
|
||||
}
|
||||
else {
|
||||
bytecodeEnhancementMetadata = new BytecodeEnhancementMetadataNonPojoImpl( persistentClass.getEntityName() );
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.tuple.entity;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.EntityNameResolver;
|
||||
|
@ -188,10 +189,9 @@ public interface EntityTuplizer extends Tuplizer {
|
|||
* Called just after the entities properties have been initialized.
|
||||
*
|
||||
* @param entity The entity being initialized.
|
||||
* @param lazyPropertiesAreUnfetched Are defined lazy properties currently unfecthed
|
||||
* @param session The session initializing this entity.
|
||||
*/
|
||||
void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session);
|
||||
void afterInitialize(Object entity, SessionImplementor session);
|
||||
|
||||
/**
|
||||
* Does this entity, for this mode, present a possibility for proxying?
|
||||
|
@ -229,21 +229,6 @@ public interface EntityTuplizer extends Tuplizer {
|
|||
*/
|
||||
Class getConcreteProxyClass();
|
||||
|
||||
/**
|
||||
* Does the given entity instance have any currently uninitialized lazy properties?
|
||||
*
|
||||
* @param entity The entity to be check for uninitialized lazy properties.
|
||||
* @return True if uninitialized lazy properties were found; false otherwise.
|
||||
*/
|
||||
boolean hasUninitializedLazyProperties(Object entity);
|
||||
|
||||
/**
|
||||
* Is it an instrumented POJO?
|
||||
*
|
||||
* @return {@code true} if the entity class is instrumented; {@code false} otherwise.
|
||||
*/
|
||||
boolean isInstrumented();
|
||||
|
||||
/**
|
||||
* Get any {@link EntityNameResolver EntityNameResolvers} associated with this {@link Tuplizer}.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.tuple.entity;
|
||||
|
||||
import org.hibernate.PropertyNotFoundException;
|
||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||
import org.hibernate.bytecode.spi.ReflectionOptimizer;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.tuple.PojoInstantiator;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class PojoEntityInstantiator extends PojoInstantiator {
|
||||
private final EntityMetamodel entityMetamodel;
|
||||
private final Class proxyInterface;
|
||||
private final boolean applyBytecodeInterception;
|
||||
|
||||
public PojoEntityInstantiator(
|
||||
EntityMetamodel entityMetamodel,
|
||||
PersistentClass persistentClass,
|
||||
ReflectionOptimizer.InstantiationOptimizer optimizer) {
|
||||
super(
|
||||
persistentClass.getMappedClass(),
|
||||
optimizer,
|
||||
persistentClass.hasEmbeddedIdentifier()
|
||||
);
|
||||
this.entityMetamodel = entityMetamodel;
|
||||
|
||||
this.proxyInterface = persistentClass.getProxyInterface();
|
||||
this.applyBytecodeInterception = PersistentAttributeInterceptable.class.isAssignableFrom( persistentClass.getMappedClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object applyInterception(Object entity) {
|
||||
if ( !applyBytecodeInterception ) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
PersistentAttributeInterceptor interceptor = new LazyAttributeLoadingInterceptor(
|
||||
entityMetamodel.getName(),
|
||||
entityMetamodel.getBytecodeEnhancementMetadata()
|
||||
.getLazyAttributesMetadata()
|
||||
.getLazyAttributeNames(),
|
||||
null
|
||||
);
|
||||
( (PersistentAttributeInterceptable) entity ).$$_hibernate_setInterceptor( interceptor );
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInstance(Object object) {
|
||||
return super.isInstance( object ) ||
|
||||
//this one needed only for guessEntityMode()
|
||||
( proxyInterface!=null && proxyInterface.isInstance(object) );
|
||||
}
|
||||
|
||||
}
|
|
@ -8,8 +8,6 @@ package org.hibernate.tuple.entity;
|
|||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -53,10 +51,11 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
|||
private final Class mappedClass;
|
||||
private final Class proxyInterface;
|
||||
private final boolean lifecycleImplementor;
|
||||
private final Set<String> lazyPropertyNames;
|
||||
private final ReflectionOptimizer optimizer;
|
||||
|
||||
private final boolean isBytecodeEnhanced;
|
||||
|
||||
|
||||
public PojoEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
|
||||
super( entityMetamodel, mappedEntity );
|
||||
this.mappedClass = mappedEntity.getMappedClass();
|
||||
|
@ -64,16 +63,6 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
|||
this.lifecycleImplementor = Lifecycle.class.isAssignableFrom( mappedClass );
|
||||
this.isBytecodeEnhanced = entityMetamodel.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
|
||||
|
||||
Iterator iter = mappedEntity.getPropertyClosureIterator();
|
||||
Set<String> tmpLazyPropertyNames = new HashSet<String>( );
|
||||
while ( iter.hasNext() ) {
|
||||
Property property = (Property) iter.next();
|
||||
if ( property.isLazy() ) {
|
||||
tmpLazyPropertyNames.add( property.getName() );
|
||||
}
|
||||
}
|
||||
lazyPropertyNames = tmpLazyPropertyNames.isEmpty() ? null : Collections.unmodifiableSet( tmpLazyPropertyNames );
|
||||
|
||||
String[] getterNames = new String[propertySpan];
|
||||
String[] setterNames = new String[propertySpan];
|
||||
Class[] propTypes = new Class[propertySpan];
|
||||
|
@ -200,12 +189,12 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
||||
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
|
||||
if ( optimizer == null ) {
|
||||
return new PojoInstantiator( persistentClass, null );
|
||||
return new PojoEntityInstantiator( entityMetamodel, persistentClass, null );
|
||||
}
|
||||
else {
|
||||
return new PojoInstantiator( persistentClass, optimizer.getInstantiationOptimizer() );
|
||||
return new PojoEntityInstantiator( entityMetamodel, persistentClass, optimizer.getInstantiationOptimizer() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,38 +270,35 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
|||
//TODO: need to make the majority of this functionality into a top-level support class for custom impl support
|
||||
|
||||
@Override
|
||||
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
|
||||
// new bytecode enhancement lazy interception
|
||||
public void afterInitialize(Object entity, SessionImplementor session) {
|
||||
|
||||
// moving to multiple fetch groups, the idea of `lazyPropertiesAreUnfetched` really
|
||||
// needs to become either:
|
||||
// 1) the names of all un-fetched fetch groups
|
||||
// 2) the names of all fetched fetch groups
|
||||
// probably (2) is best
|
||||
//
|
||||
// ultimately this comes from EntityEntry, although usage-search seems to show it is never updated there.
|
||||
//
|
||||
// also org.hibernate.persister.entity.AbstractEntityPersister.initializeLazyPropertiesFromDatastore()
|
||||
// needs to be re-worked
|
||||
|
||||
if ( entity instanceof PersistentAttributeInterceptable ) {
|
||||
if ( lazyPropertiesAreUnfetched && getEntityMetamodel().hasLazyProperties() ) {
|
||||
PersistentAttributeInterceptor interceptor = new LazyAttributeLoadingInterceptor( session, lazyPropertyNames, getEntityName() );
|
||||
( (PersistentAttributeInterceptable) entity ).$$_hibernate_setInterceptor( interceptor );
|
||||
final LazyAttributeLoadingInterceptor interceptor = getEntityMetamodel().getBytecodeEnhancementMetadata().extractInterceptor( entity );
|
||||
if ( interceptor == null ) {
|
||||
getEntityMetamodel().getBytecodeEnhancementMetadata().injectInterceptor( entity, session );
|
||||
}
|
||||
}
|
||||
|
||||
// also clear the fields that are marked as dirty in the dirtyness tracker
|
||||
if ( entity instanceof SelfDirtinessTracker ) {
|
||||
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUninitializedLazyProperties(Object entity) {
|
||||
if ( getEntityMetamodel().hasLazyProperties() ) {
|
||||
if ( entity instanceof PersistentAttributeInterceptable ) {
|
||||
PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
|
||||
if ( interceptor != null && interceptor instanceof LazyAttributeLoadingInterceptor ) {
|
||||
return ( (LazyAttributeLoadingInterceptor) interceptor ).hasAnyUninitializedAttributes();
|
||||
else {
|
||||
if ( interceptor.getLinkedSession() == null ) {
|
||||
interceptor.setSession( session );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInstrumented() {
|
||||
return isBytecodeEnhanced;
|
||||
// clear the fields that are marked as dirty in the dirtyness tracker
|
||||
if ( entity instanceof SelfDirtinessTracker ) {
|
||||
( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,10 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.engine.spi;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
|
@ -18,8 +14,13 @@ import java.io.ObjectOutputStream;
|
|||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.internal.MutableEntityEntry;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Tests for setting and getting the enum/boolean values stored in the compressed state int.
|
||||
*
|
||||
|
@ -35,7 +36,6 @@ public class EntityEntryTest {
|
|||
assertEquals( Status.MANAGED, entityEntry.getStatus() );
|
||||
assertEquals( true, entityEntry.isExistsInDatabase() );
|
||||
assertEquals( true, entityEntry.isBeingReplicated() );
|
||||
assertEquals( true, entityEntry.isLoadedWithLazyPropertiesUnfetched() );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -47,7 +47,6 @@ public class EntityEntryTest {
|
|||
assertEquals( Status.MANAGED, entityEntry.getStatus() );
|
||||
assertEquals( true, entityEntry.isExistsInDatabase() );
|
||||
assertEquals( true, entityEntry.isBeingReplicated() );
|
||||
assertEquals( true, entityEntry.isLoadedWithLazyPropertiesUnfetched() );
|
||||
|
||||
// When
|
||||
entityEntry.setLockMode( LockMode.PESSIMISTIC_READ );
|
||||
|
@ -57,7 +56,6 @@ public class EntityEntryTest {
|
|||
assertEquals( Status.MANAGED, entityEntry.getStatus() );
|
||||
assertEquals( true, entityEntry.isExistsInDatabase() );
|
||||
assertEquals( true, entityEntry.isBeingReplicated() );
|
||||
assertEquals( true, entityEntry.isLoadedWithLazyPropertiesUnfetched() );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -73,7 +71,6 @@ public class EntityEntryTest {
|
|||
assertEquals( Status.DELETED, entityEntry.getStatus() );
|
||||
assertEquals( true, entityEntry.isExistsInDatabase() );
|
||||
assertEquals( true, entityEntry.isBeingReplicated() );
|
||||
assertEquals( true, entityEntry.isLoadedWithLazyPropertiesUnfetched() );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -89,7 +86,6 @@ public class EntityEntryTest {
|
|||
assertEquals( Status.GONE, entityEntry.getStatus() );
|
||||
assertEquals( false, entityEntry.isExistsInDatabase() );
|
||||
assertEquals( true, entityEntry.isBeingReplicated() );
|
||||
assertEquals( true, entityEntry.isLoadedWithLazyPropertiesUnfetched() );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -108,23 +104,30 @@ public class EntityEntryTest {
|
|||
assertEquals( Status.MANAGED, deserializedEntry.getStatus() );
|
||||
assertEquals( true, deserializedEntry.isExistsInDatabase() );
|
||||
assertEquals( true, deserializedEntry.isBeingReplicated() );
|
||||
assertEquals( true, deserializedEntry.isLoadedWithLazyPropertiesUnfetched() );
|
||||
}
|
||||
|
||||
private EntityEntry createEntityEntry() {
|
||||
|
||||
return new MutableEntityEntry(
|
||||
Status.MANAGED, // status
|
||||
new Object[]{}, // loadedState
|
||||
1L, // rowId
|
||||
42L, // id
|
||||
23L, // version
|
||||
LockMode.OPTIMISTIC, // lockMode
|
||||
true, // existsInDatabase
|
||||
null, // persister
|
||||
true, // disableVersionIncrement
|
||||
true, // lazyPropertiesAreUnfetched
|
||||
getPersistenceContextMock() // persistenceContext)
|
||||
// status
|
||||
Status.MANAGED,
|
||||
// loadedState
|
||||
new Object[]{},
|
||||
// rowId
|
||||
1L,
|
||||
// id
|
||||
42L,
|
||||
// version
|
||||
23L,
|
||||
// lockMode
|
||||
LockMode.OPTIMISTIC,
|
||||
// existsInDatabase
|
||||
true,
|
||||
// persister
|
||||
null,
|
||||
// disableVersionIncrement
|
||||
true,
|
||||
getPersistenceContextMock()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,19 +19,21 @@ import org.hibernate.tuple.entity.PojoEntityTuplizer;
|
|||
*/
|
||||
public class DynamicEntityTuplizer extends PojoEntityTuplizer {
|
||||
|
||||
public DynamicEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
|
||||
super( entityMetamodel, mappedEntity );
|
||||
}
|
||||
|
||||
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
||||
return new DynamicInstantiator( persistentClass.getEntityName() );
|
||||
}
|
||||
|
||||
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
||||
// allows defining a custom proxy factory, which is responsible for
|
||||
// generating lazy proxies for a given entity.
|
||||
//
|
||||
// Here we simply use the default...
|
||||
return super.buildProxyFactory( persistentClass, idGetter, idSetter );
|
||||
}
|
||||
public DynamicEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
|
||||
super( entityMetamodel, mappedEntity );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
|
||||
return new DynamicInstantiator( persistentClass.getEntityName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
||||
// allows defining a custom proxy factory, which is responsible for
|
||||
// generating lazy proxies for a given entity.
|
||||
//
|
||||
// Here we simply use the default...
|
||||
return super.buildProxyFactory( persistentClass, idGetter, idSetter );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.hibernate.test.bytecode.enhancement.lazy.LazyLoadingIntegrationTestTa
|
|||
import org.hibernate.test.bytecode.enhancement.lazy.LazyLoadingTestTask;
|
||||
import org.hibernate.test.bytecode.enhancement.lazy.basic.LazyBasicFieldAccessTestTask;
|
||||
import org.hibernate.test.bytecode.enhancement.lazy.basic.LazyBasicPropertyAccessTestTask;
|
||||
import org.hibernate.test.bytecode.enhancement.lazy.group.LazyGroupAccessTestTask;
|
||||
import org.hibernate.test.bytecode.enhancement.lazyCache.InitFromCacheTestTask;
|
||||
import org.hibernate.test.bytecode.enhancement.merge.CompositeMergeTestTask;
|
||||
import org.hibernate.test.bytecode.enhancement.pk.EmbeddedPKTestTask;
|
||||
|
@ -72,6 +73,12 @@ public class EnhancerTest extends BaseUnitTestCase {
|
|||
EnhancerTestUtils.runEnhancerTestTask( LazyCollectionLoadingTestTask.class );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-10267" )
|
||||
public void testLazyGroups() {
|
||||
EnhancerTestUtils.runEnhancerTestTask( LazyGroupAccessTestTask.class );
|
||||
}
|
||||
|
||||
@Test(timeout = 10000)
|
||||
@TestForIssue( jiraKey = "HHH-10055" )
|
||||
@FailureExpected( jiraKey = "HHH-10055" )
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
package org.hibernate.test.bytecode.enhancement.basic;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
|
||||
|
||||
/**
|
||||
|
@ -112,4 +114,14 @@ public class ObjectAttributeMarkerInterceptor implements PersistentAttributeInte
|
|||
public Object writeObject(Object obj, String name, Object oldValue, Object newValue) {
|
||||
return WRITE_MARKER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getInitializedLazyAttributeNames() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attributeInitialized(String name) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,13 @@ public class Child {
|
|||
@LazyToOne(LazyToOneOption.NO_PROXY)
|
||||
Parent parent;
|
||||
|
||||
public Child() {
|
||||
}
|
||||
|
||||
public Child(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask;
|
|||
import org.hibernate.testing.bytecode.enhancement.EnhancerTestUtils;
|
||||
import org.junit.Assert;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Luis Barreiro
|
||||
*/
|
||||
|
@ -43,8 +46,9 @@ public class LazyLoadingTestTask extends AbstractEnhancerTestTask {
|
|||
Parent parent = new Parent();
|
||||
parent.setChildren(new ArrayList<Child>());
|
||||
for ( int i = 0; i < CHILDREN_SIZE; i++ ) {
|
||||
final Child child = new Child();
|
||||
final Child child = new Child( "Child #" + i );
|
||||
child.setParent( parent );
|
||||
parent.getChildren().add( child );
|
||||
s.persist( child );
|
||||
lastChildID = child.getId();
|
||||
}
|
||||
|
@ -62,11 +66,17 @@ public class LazyLoadingTestTask extends AbstractEnhancerTestTask {
|
|||
|
||||
Child loadedChild = s.load( Child.class, lastChildID );
|
||||
|
||||
Object nameByReflection = EnhancerTestUtils.getFieldByReflection( loadedChild, "name" );
|
||||
Assert.assertNotNull( "Non-lazy field 'name' was not loaded", nameByReflection );
|
||||
|
||||
Object parentByReflection = EnhancerTestUtils.getFieldByReflection( loadedChild, "parent" );
|
||||
Assert.assertNull( "Lazy field 'parent' is initialized", parentByReflection );
|
||||
Assert.assertFalse( loadedChild instanceof HibernateProxy );
|
||||
|
||||
Parent loadedParent = loadedChild.getParent();
|
||||
assertThat( loadedChild.getName(), notNullValue() );
|
||||
assertThat( loadedParent, notNullValue() );
|
||||
assertThat( loadedChild.getParent(), notNullValue() );
|
||||
|
||||
EnhancerTestUtils.checkDirtyTracking( loadedChild );
|
||||
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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.group;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
import org.hibernate.annotations.LazyGroup;
|
||||
import org.hibernate.annotations.LazyToOne;
|
||||
import org.hibernate.annotations.LazyToOneOption;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
public class Child {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
Long id;
|
||||
String name;
|
||||
@Basic( fetch = FetchType.LAZY )
|
||||
String nickName;
|
||||
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
@LazyToOne(LazyToOneOption.NO_PROXY)
|
||||
Parent parent;
|
||||
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
@LazyToOne(LazyToOneOption.NO_PROXY)
|
||||
@LazyGroup( "SECONDARY" )
|
||||
Parent alternateParent;
|
||||
|
||||
public Child() {
|
||||
}
|
||||
|
||||
public Child(String name, String nickName) {
|
||||
this.name = name;
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getNickName() {
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public void setNickName(String nickName) {
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public Parent getAlternateParent() {
|
||||
return alternateParent;
|
||||
}
|
||||
|
||||
public void setAlternateParent(Parent alternateParent) {
|
||||
this.alternateParent = alternateParent;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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.group;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
|
||||
import org.hibernate.testing.bytecode.enhancement.EnhancerTestUtils;
|
||||
import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask;
|
||||
import org.junit.Assert;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LazyGroupAccessTestTask extends AbstractEnhancerTestTask {
|
||||
|
||||
@Override
|
||||
public Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] { Child.class, Parent.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
Configuration cfg = new Configuration();
|
||||
cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" );
|
||||
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" );
|
||||
super.prepare( cfg );
|
||||
|
||||
Session s = getFactory().openSession();
|
||||
s.beginTransaction();
|
||||
|
||||
Child c1 = new Child( "steve", "hibernater" );
|
||||
Child c2 = new Child( "sally", "Joe Mama" );
|
||||
|
||||
Parent p1 = new Parent( "Hibernate" );
|
||||
Parent p2 = new Parent( "Swimming" );
|
||||
|
||||
c1.setParent( p1 );
|
||||
p1.getChildren().add( c1 );
|
||||
|
||||
c1.setAlternateParent( p2 );
|
||||
p2.getAlternateChildren().add( c1 );
|
||||
|
||||
c2.setAlternateParent( p1 );
|
||||
p1.getAlternateChildren().add( c2 );
|
||||
|
||||
c2.setParent( p2 );
|
||||
p2.getChildren().add( c2 );
|
||||
|
||||
s.save( p1 );
|
||||
s.save( p2 );
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Session s = getFactory().openSession();
|
||||
s.beginTransaction();
|
||||
|
||||
Child c1 = (Child) s.createQuery( "from Child c where c.name = :name" ).setString( "name", "steve" ).uniqueResult();
|
||||
|
||||
// verify the expected initial loaded state
|
||||
assertLoaded( c1, "name" );
|
||||
assertNotLoaded( c1, "nickName" );
|
||||
assertNotLoaded( c1, "parent" );
|
||||
assertNotLoaded( c1, "alternateParent" );
|
||||
|
||||
// Now lets access nickName which ought to initialize nickName and parent, but not alternateParent
|
||||
c1.getNickName();
|
||||
assertLoaded( c1, "nickName" );
|
||||
assertLoaded( c1, "parent" );
|
||||
assertNotLoaded( c1, "alternateParent" );
|
||||
assertEquals( "Hibernate", c1.getParent().getNombre() );
|
||||
assertFalse( c1.getParent() instanceof HibernateProxy );
|
||||
|
||||
Child c2 = (Child) s.createQuery( "from Child c where c.name = :name" ).setString( "name", "sally" ).uniqueResult();
|
||||
|
||||
// verify the expected initial loaded state
|
||||
assertLoaded( c2, "name" );
|
||||
assertNotLoaded( c2, "nickName" );
|
||||
assertNotLoaded( c2, "parent" );
|
||||
assertNotLoaded( c2, "alternateParent" );
|
||||
|
||||
// Now lets access alternateParent which ought to initialize alternateParent and nothing else
|
||||
c2.getAlternateParent();
|
||||
assertNotLoaded( c2, "nickName" );
|
||||
assertNotLoaded( c2, "parent" );
|
||||
assertLoaded( c2, "alternateParent" );
|
||||
assertEquals( "Hibernate", c2.getAlternateParent().getNombre() );
|
||||
assertFalse( c2.getAlternateParent() instanceof HibernateProxy );
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
private void assertLoaded(Object owner, String name) {
|
||||
// NOTE we assume null == not-loaded
|
||||
Object fieldByReflection = EnhancerTestUtils.getFieldByReflection( owner, name );
|
||||
assertNotNull( "Expecting field '" + name + "' to be loaded, but it was not", fieldByReflection );
|
||||
}
|
||||
|
||||
private void assertNotLoaded(Object owner, String name) {
|
||||
// NOTE we assume null == not-loaded
|
||||
Object fieldByReflection = EnhancerTestUtils.getFieldByReflection( owner, name );
|
||||
assertNull( "Expecting field '" + name + "' to be not loaded, but it was", fieldByReflection );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanup() {
|
||||
Session s = getFactory().openSession();
|
||||
s.beginTransaction();
|
||||
|
||||
s.createQuery( "delete Child" ).executeUpdate();
|
||||
s.createQuery( "delete Parent" ).executeUpdate();
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.group;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
public class Parent {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
Long id;
|
||||
String nombre;
|
||||
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
List<Child> children = new ArrayList<Child>();
|
||||
@OneToMany(mappedBy = "alternateParent", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
List<Child> alternateChildren = new ArrayList<Child>();
|
||||
|
||||
public Parent() {
|
||||
}
|
||||
|
||||
public Parent(String nombre) {
|
||||
this.nombre = nombre;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNombre() {
|
||||
return nombre;
|
||||
}
|
||||
|
||||
public void setNombre(String nombre) {
|
||||
this.nombre = nombre;
|
||||
}
|
||||
|
||||
public List<Child> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Child> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public List<Child> getAlternateChildren() {
|
||||
return alternateChildren;
|
||||
}
|
||||
|
||||
public void setAlternateChildren(List<Child> alternateChildren) {
|
||||
this.alternateChildren = alternateChildren;
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@ public abstract class AbstractCachingTestTask implements EnhancerTestTask {
|
|||
StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder();
|
||||
registryBuilder.applySetting( AvailableSettings.GENERATE_STATISTICS, "true" );
|
||||
registryBuilder.applySetting( AvailableSettings.HBM2DDL_AUTO, "create-drop" );
|
||||
registryBuilder.applySetting( AvailableSettings.USE_SECOND_LEVEL_CACHE, "true" );
|
||||
registryBuilder.addService( ClassLoaderService.class, new ClassLoaderServiceImpl( Thread.currentThread().getContextClassLoader() ) );
|
||||
StandardServiceRegistry registry = registryBuilder.build();
|
||||
|
||||
|
|
|
@ -8,10 +8,14 @@ package org.hibernate.test.bytecode.enhancement.lazyCache;
|
|||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cache.spi.entry.StandardCacheEntryImpl;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
import org.hibernate.testing.cache.BaseRegion;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
|
@ -20,42 +24,47 @@ import static org.junit.Assert.assertTrue;
|
|||
public class InitFromCacheTestTask extends AbstractCachingTestTask {
|
||||
@Override
|
||||
public void execute() {
|
||||
Session s;
|
||||
Transaction tx;
|
||||
EntityPersister p = sessionFactory().getEntityPersister( Document.class.getName() );
|
||||
assertTrue( p.hasCache() );
|
||||
BaseRegion region = (BaseRegion) p.getCacheAccessStrategy().getRegion();
|
||||
|
||||
s = sessionFactory().openSession();
|
||||
tx = s.beginTransaction();
|
||||
Session s = sessionFactory().openSession();
|
||||
s.beginTransaction();
|
||||
s.persist( new Document("HiA", "Hibernate book", "Hibernate is....") );
|
||||
tx.commit();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = sessionFactory().openSession();
|
||||
tx = s.beginTransaction();
|
||||
s.createQuery("from Document fetch all properties").uniqueResult();
|
||||
tx.commit();
|
||||
s.beginTransaction();
|
||||
Document d = (Document) s.createQuery( "from Document fetch all properties").uniqueResult();
|
||||
assertTrue( Hibernate.isPropertyInitialized( d, "text") );
|
||||
assertTrue( Hibernate.isPropertyInitialized( d, "summary") );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
StandardCacheEntryImpl cacheEntry = (StandardCacheEntryImpl) region.getDataMap().get( p.getCacheAccessStrategy().generateCacheKey( d.getId(), p, sessionFactory(), null ) );
|
||||
assertNotNull( cacheEntry );
|
||||
sessionFactory().getStatistics().clear();
|
||||
|
||||
s = sessionFactory().openSession();
|
||||
tx = s.beginTransaction();
|
||||
Document d = (Document) s.createCriteria(Document.class).uniqueResult();
|
||||
s.beginTransaction();
|
||||
d = (Document) s.createCriteria(Document.class).uniqueResult();
|
||||
assertFalse( Hibernate.isPropertyInitialized( d, "text") );
|
||||
assertFalse( Hibernate.isPropertyInitialized(d, "summary") );
|
||||
assertEquals( "Hibernate is....", d.getText() );
|
||||
assertTrue( Hibernate.isPropertyInitialized(d, "text") );
|
||||
assertTrue( Hibernate.isPropertyInitialized(d, "summary") );
|
||||
tx.commit();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
assertEquals( 2, sessionFactory().getStatistics().getPrepareStatementCount() );
|
||||
|
||||
s = sessionFactory().openSession();
|
||||
tx = s.beginTransaction();
|
||||
s.beginTransaction();
|
||||
d = s.get(Document.class, d.getId());
|
||||
assertFalse( Hibernate.isPropertyInitialized(d, "text") );
|
||||
assertFalse( Hibernate.isPropertyInitialized(d, "summary") );
|
||||
tx.commit();
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.sql.ResultSet;
|
|||
import java.sql.SQLException;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -45,9 +46,9 @@ import org.hibernate.persister.walking.spi.AttributeDefinition;
|
|||
import org.hibernate.persister.walking.spi.CollectionElementDefinition;
|
||||
import org.hibernate.persister.walking.spi.CollectionIndexDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.VersionType;
|
||||
|
@ -453,7 +454,8 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
|
||||
public void afterInitialize(Object entity, SessionImplementor session) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,10 +22,12 @@ public class MyEntityTuplizer extends PojoEntityTuplizer {
|
|||
super( entityMetamodel, mappedEntity );
|
||||
}
|
||||
|
||||
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
||||
@Override
|
||||
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
|
||||
return new MyEntityInstantiator( persistentClass.getEntityName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
||||
// allows defining a custom proxy factory, which is responsible for
|
||||
// generating lazy proxies for a given entity.
|
||||
|
|
|
@ -26,14 +26,17 @@ public class MyEntityTuplizer extends PojoEntityTuplizer {
|
|||
super( entityMetamodel, mappedEntity );
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityNameResolver[] getEntityNameResolvers() {
|
||||
return new EntityNameResolver[] { MyEntityNameResolver.INSTANCE };
|
||||
}
|
||||
|
||||
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
||||
@Override
|
||||
protected Instantiator buildInstantiator(EntityMetamodel entityMetamodel, PersistentClass persistentClass) {
|
||||
return new MyEntityInstantiator( persistentClass.getEntityName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
|
||||
String entityName = ProxyHelper.extractEntityName( entityInstance );
|
||||
if ( entityName == null ) {
|
||||
|
@ -42,6 +45,7 @@ public class MyEntityTuplizer extends PojoEntityTuplizer {
|
|||
return entityName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
||||
// allows defining a custom proxy factory, which is responsible for
|
||||
// generating lazy proxies for a given entity.
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.io.Serializable;
|
|||
import java.util.Comparator;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -45,9 +46,9 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.spi.PersisterCreationContext;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
||||
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.VersionType;
|
||||
|
@ -324,7 +325,6 @@ public class CustomPersister implements EntityPersister {
|
|||
clone,
|
||||
this,
|
||||
LockMode.NONE,
|
||||
false,
|
||||
session
|
||||
);
|
||||
TwoPhaseLoad.postHydrate(
|
||||
|
@ -333,7 +333,6 @@ public class CustomPersister implements EntityPersister {
|
|||
null,
|
||||
clone,
|
||||
LockMode.NONE,
|
||||
false,
|
||||
session
|
||||
);
|
||||
TwoPhaseLoad.initializeEntity(
|
||||
|
@ -561,7 +560,7 @@ public class CustomPersister implements EntityPersister {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterInitialize(Object entity, boolean fetched, SessionImplementor session) {
|
||||
public void afterInitialize(Object entity, SessionImplementor session) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -594,7 +593,6 @@ public class CustomPersister implements EntityPersister {
|
|||
return new StandardCacheEntryImpl(
|
||||
state,
|
||||
this,
|
||||
this.hasUninitializedLazyProperties( entity ),
|
||||
version,
|
||||
session,
|
||||
entity
|
||||
|
|
|
@ -474,7 +474,7 @@ public class PersisterClassProviderTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
|
||||
public void afterInitialize(Object entity, SessionImplementor session) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -213,7 +213,6 @@ public abstract class EnhancerTestUtils extends BaseUnitTestCase {
|
|||
false,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.hibernate.cache.spi.Region;
|
|||
/**
|
||||
* @author Strong Liu
|
||||
*/
|
||||
class BaseRegion implements Region {
|
||||
public class BaseRegion implements Region {
|
||||
protected final Map cache = new ConcurrentHashMap();
|
||||
private final String name;
|
||||
private static int timeout = Timestamper.ONE_MS * 60000; //60s
|
||||
|
@ -69,4 +69,8 @@ class BaseRegion implements Region {
|
|||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public Map getDataMap() {
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue