HHH-4726 - Add support for delete-orphan cascading to <one-to-one/>
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18568 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
7fa50f7a18
commit
29152a8390
|
@ -1064,10 +1064,10 @@ public final class HbmBinder {
|
|||
// COLUMN(S)
|
||||
Attribute columnAttribute = node.attribute( "column" );
|
||||
if ( columnAttribute == null ) {
|
||||
Iterator iter = node.elementIterator();
|
||||
Iterator itr = node.elementIterator();
|
||||
int count = 0;
|
||||
while ( iter.hasNext() ) {
|
||||
Element columnElement = (Element) iter.next();
|
||||
while ( itr.hasNext() ) {
|
||||
Element columnElement = (Element) itr.next();
|
||||
if ( columnElement.getName().equals( "column" ) ) {
|
||||
Column column = new Column();
|
||||
column.setValue( simpleValue );
|
||||
|
@ -1115,6 +1115,9 @@ public final class HbmBinder {
|
|||
Column column = new Column();
|
||||
column.setValue( simpleValue );
|
||||
bindColumn( node, column, isNullable );
|
||||
if ( column.isUnique() && ManyToOne.class.isInstance( simpleValue ) ) {
|
||||
( (ManyToOne) simpleValue ).markAsLogicalOneToOne();
|
||||
}
|
||||
final String columnName = columnAttribute.getValue();
|
||||
String logicalColumnName = mappings.getNamingStrategy().logicalColumnName(
|
||||
columnName, propertyPath
|
||||
|
@ -1617,7 +1620,9 @@ public final class HbmBinder {
|
|||
|
||||
String cascade = node.attributeValue( "cascade" );
|
||||
if ( cascade != null && cascade.indexOf( "delete-orphan" ) >= 0 ) {
|
||||
throw new MappingException( "many-to-one attributes do not support orphan delete: " + path );
|
||||
if ( !manyToOne.isLogicalOneToOne() ) {
|
||||
throw new MappingException( "many-to-one attributes do not support orphan delete: " + path );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,13 +20,14 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.engine;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -36,6 +37,7 @@ import org.hibernate.collection.PersistentCollection;
|
|||
import org.hibernate.event.EventSource;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
import org.hibernate.type.AbstractComponentType;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.CollectionType;
|
||||
|
@ -148,7 +150,8 @@ public final class Cascade {
|
|||
EntityMode entityMode = eventSource.getEntityMode();
|
||||
boolean hasUninitializedLazyProperties = persister.hasUninitializedLazyProperties( parent, entityMode );
|
||||
for ( int i=0; i<types.length; i++) {
|
||||
CascadeStyle style = cascadeStyles[i];
|
||||
final CascadeStyle style = cascadeStyles[i];
|
||||
final String propertyName = persister.getPropertyNames()[i];
|
||||
if ( hasUninitializedLazyProperties && persister.getPropertyLaziness()[i] && ! action.performOnLazyProperty() ) {
|
||||
//do nothing to avoid a lazy property initialization
|
||||
continue;
|
||||
|
@ -160,6 +163,7 @@ public final class Cascade {
|
|||
persister.getPropertyValue( parent, i, entityMode ),
|
||||
types[i],
|
||||
style,
|
||||
propertyName,
|
||||
anything,
|
||||
false
|
||||
);
|
||||
|
@ -189,6 +193,7 @@ public final class Cascade {
|
|||
final Object child,
|
||||
final Type type,
|
||||
final CascadeStyle style,
|
||||
final String propertyName,
|
||||
final Object anything,
|
||||
final boolean isCascadeDeleteEnabled) throws HibernateException {
|
||||
|
||||
|
@ -207,7 +212,7 @@ public final class Cascade {
|
|||
}
|
||||
}
|
||||
else if ( type.isComponentType() ) {
|
||||
cascadeComponent( parent, child, (AbstractComponentType) type, anything );
|
||||
cascadeComponent( parent, child, (AbstractComponentType) type, propertyName, anything );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -222,11 +227,34 @@ public final class Cascade {
|
|||
final EntityEntry entry = eventSource.getPersistenceContext().getEntry( parent );
|
||||
if ( entry != null ) {
|
||||
final EntityType entityType = (EntityType) type;
|
||||
final Object loadedValue = entry.getLoadedValue( entityType.getPropertyName() );
|
||||
final Object loadedValue;
|
||||
if ( componentPathStack.isEmpty() ) {
|
||||
// association defined on entity
|
||||
loadedValue = entry.getLoadedValue( propertyName );
|
||||
}
|
||||
else {
|
||||
// association defined on component
|
||||
// todo : this is currently unsupported because of the fact that
|
||||
// we do not know the loaded state of this value properly
|
||||
// and doing so would be very difficult given how components and
|
||||
// entities are loaded (and how 'loaded state' is put into the
|
||||
// EntityEntry). Solutions here are to either:
|
||||
// 1) properly account for components as a 2-phase load construct
|
||||
// 2) just assume the association was just now orphaned and
|
||||
// issue the orphan delete. This would require a special
|
||||
// set of SQL statements though since we do not know the
|
||||
// orphaned value, something a delete with a subquery to
|
||||
// match the owner.
|
||||
// final String propertyPath = composePropertyPath( entityType.getPropertyName() );
|
||||
loadedValue = null;
|
||||
}
|
||||
if ( loadedValue != null ) {
|
||||
final String entityName = entityType.getAssociatedEntityName();
|
||||
final String entityName = entry.getPersister().getEntityName();
|
||||
if ( log.isTraceEnabled() ) {
|
||||
log.trace( "deleting orphaned entity instance: " + entityName );
|
||||
final Serializable id = entry.getPersister()
|
||||
.getIdentifier( loadedValue, eventSource.getEntityMode() );
|
||||
final String description = MessageHelper.infoString( entityName, id );
|
||||
log.trace( "deleting orphaned entity instance: " + description );
|
||||
}
|
||||
eventSource.delete( entityName, loadedValue, false, new HashSet() );
|
||||
}
|
||||
|
@ -245,21 +273,26 @@ public final class Cascade {
|
|||
* @return True if the attribute represents a logical one to one association
|
||||
*/
|
||||
private boolean isLogicalOneToOne(Type type) {
|
||||
if ( ! type.isEntityType() ) {
|
||||
return false;
|
||||
}
|
||||
final EntityType entityType = (EntityType) type;
|
||||
if ( entityType.isOneToOne() ) {
|
||||
// physical one-to-one
|
||||
return true;
|
||||
}
|
||||
// todo : still need to handle the many-to-one w/ property-ref
|
||||
// actually there is a question about whether the constrained side
|
||||
// can declare the orphan-delete. If not, then the side declaring
|
||||
// the orphan-delete can only ever be a <one-to-one/>
|
||||
return false;
|
||||
return type.isEntityType() && ( (EntityType) type ).isLogicalOneToOne();
|
||||
}
|
||||
|
||||
private String composePropertyPath(String propertyName) {
|
||||
if ( componentPathStack.isEmpty() ) {
|
||||
return propertyName;
|
||||
}
|
||||
else {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
Iterator itr = componentPathStack.iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
buffer.append( itr.next() ).append( '.' );
|
||||
}
|
||||
buffer.append( propertyName );
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private Stack componentPathStack = new Stack();
|
||||
|
||||
private boolean cascadeAssociationNow(AssociationType associationType) {
|
||||
return associationType.getForeignKeyDirection().cascadeNow(cascadeTo) &&
|
||||
( eventSource.getEntityMode()!=EntityMode.DOM4J || associationType.isEmbeddedInXML() );
|
||||
|
@ -269,22 +302,27 @@ public final class Cascade {
|
|||
final Object parent,
|
||||
final Object child,
|
||||
final AbstractComponentType componentType,
|
||||
final String componentPropertyName,
|
||||
final Object anything) {
|
||||
Object[] children = componentType.getPropertyValues(child, eventSource);
|
||||
componentPathStack.push( componentPropertyName );
|
||||
Object[] children = componentType.getPropertyValues( child, eventSource );
|
||||
Type[] types = componentType.getSubtypes();
|
||||
for ( int i=0; i<types.length; i++ ) {
|
||||
CascadeStyle componentPropertyStyle = componentType.getCascadeStyle(i);
|
||||
final CascadeStyle componentPropertyStyle = componentType.getCascadeStyle(i);
|
||||
final String subPropertyName = componentType.getPropertyNames()[i];
|
||||
if ( componentPropertyStyle.doCascade(action) ) {
|
||||
cascadeProperty(
|
||||
parent,
|
||||
children[i],
|
||||
types[i],
|
||||
componentPropertyStyle,
|
||||
subPropertyName,
|
||||
anything,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
componentPathStack.pop();
|
||||
}
|
||||
|
||||
private void cascadeAssociation(
|
||||
|
@ -389,7 +427,8 @@ public final class Cascade {
|
|||
parent,
|
||||
iter.next(),
|
||||
elemType,
|
||||
style,
|
||||
style,
|
||||
null,
|
||||
anything,
|
||||
isCascadeDeleteEnabled
|
||||
);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,7 +20,6 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.engine;
|
||||
|
||||
|
@ -29,7 +28,6 @@ import java.io.ObjectOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -84,13 +82,9 @@ public final class EntityEntry implements Serializable {
|
|||
this.loadedWithLazyPropertiesUnfetched = lazyPropertiesAreUnfetched;
|
||||
this.persister=persister;
|
||||
this.entityMode = entityMode;
|
||||
this.entityName = persister == null ?
|
||||
null : persister.getEntityName();
|
||||
this.entityName = persister == null ? null : persister.getEntityName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used during custom deserialization
|
||||
*/
|
||||
private EntityEntry(
|
||||
final SessionFactoryImplementor factory,
|
||||
final String entityName,
|
||||
|
@ -104,6 +98,7 @@ public final class EntityEntry implements Serializable {
|
|||
final boolean existsInDatabase,
|
||||
final boolean isBeingReplicated,
|
||||
final boolean loadedWithLazyPropertiesUnfetched) {
|
||||
// Used during custom deserialization
|
||||
this.entityName = entityName;
|
||||
this.persister = ( factory == null ? null : factory.getEntityPersister( entityName ) );
|
||||
this.id = id;
|
||||
|
@ -181,10 +176,6 @@ public final class EntityEntry implements Serializable {
|
|||
return cachedEntityKey;
|
||||
}
|
||||
|
||||
void afterDeserialize(SessionFactoryImplementor factory) {
|
||||
persister = factory.getEntityPersister( entityName );
|
||||
}
|
||||
|
||||
public String getEntityName() {
|
||||
return entityName;
|
||||
}
|
||||
|
@ -198,24 +189,29 @@ public final class EntityEntry implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* After actually updating the database, update the snapshot information,
|
||||
* and escalate the lock mode
|
||||
* Handle updating the internal state of the entry after actually performing
|
||||
* the database update. Specifically we update the snapshot information and
|
||||
* escalate the lock mode
|
||||
*
|
||||
* @param entity The entity instance
|
||||
* @param updatedState The state calculated after the update (becomes the
|
||||
* new {@link #getLoadedState() loaded state}.
|
||||
* @param nextVersion The new version.
|
||||
*/
|
||||
public void postUpdate(Object entity, Object[] updatedState, Object nextVersion) {
|
||||
this.loadedState = updatedState;
|
||||
|
||||
setLockMode(LockMode.WRITE);
|
||||
|
||||
|
||||
if ( getPersister().isVersioned() ) {
|
||||
this.version = nextVersion;
|
||||
getPersister().setPropertyValue(
|
||||
entity,
|
||||
getPersister().setPropertyValue(
|
||||
entity,
|
||||
getPersister().getVersionProperty(),
|
||||
nextVersion,
|
||||
entityMode
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
FieldInterceptionHelper.clearDirty( entity );
|
||||
}
|
||||
|
||||
|
@ -249,8 +245,7 @@ public final class EntityEntry implements Serializable {
|
|||
int propertyIndex = ( (UniqueKeyLoadable) persister ).getPropertyIndex(propertyName);
|
||||
return loadedState[propertyIndex];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean requiresDirtyCheck(Object entity) {
|
||||
|
||||
boolean isMutableInstance =
|
||||
|
@ -268,6 +263,7 @@ public final class EntityEntry implements Serializable {
|
|||
public void forceLocked(Object entity, Object nextVersion) {
|
||||
version = nextVersion;
|
||||
loadedState[ persister.getVersionProperty() ] = version;
|
||||
//noinspection deprecation
|
||||
setLockMode( LockMode.FORCE ); // TODO: use LockMode.PESSIMISTIC_FORCE_INCREMENT
|
||||
persister.setPropertyValue(
|
||||
entity,
|
||||
|
@ -309,13 +305,13 @@ public final class EntityEntry implements Serializable {
|
|||
return loadedWithLazyPropertiesUnfetched;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Custom serialization routine used during serialization of a
|
||||
* Session/PersistenceContext for increased performance.
|
||||
*
|
||||
* @param oos The stream to which we should write the serial data.
|
||||
* @throws java.io.IOException
|
||||
*
|
||||
* @throws IOException If a stream error occurs
|
||||
*/
|
||||
void serialize(ObjectOutputStream oos) throws IOException {
|
||||
oos.writeObject( entityName );
|
||||
|
@ -338,9 +334,12 @@ public final class EntityEntry implements Serializable {
|
|||
*
|
||||
* @param ois The stream from which to read the entry.
|
||||
* @param session The session being deserialized.
|
||||
*
|
||||
* @return The deserialized EntityEntry
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*
|
||||
* @throws IOException If a stream error occurs
|
||||
* @throws ClassNotFoundException If any of the classes declared in the stream
|
||||
* cannot be found
|
||||
*/
|
||||
static EntityEntry deserialize(
|
||||
ObjectInputStream ois,
|
||||
|
@ -353,7 +352,7 @@ public final class EntityEntry implements Serializable {
|
|||
Status.parse( ( String ) ois.readObject() ),
|
||||
( Object[] ) ois.readObject(),
|
||||
( Object[] ) ois.readObject(),
|
||||
( Object ) ois.readObject(),
|
||||
ois.readObject(),
|
||||
LockMode.parse( ( String ) ois.readObject() ),
|
||||
ois.readBoolean(),
|
||||
ois.readBoolean(),
|
||||
|
|
|
@ -38,8 +38,8 @@ import org.hibernate.type.TypeFactory;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class ManyToOne extends ToOne {
|
||||
|
||||
private boolean ignoreNotFound;
|
||||
private boolean isLogicalOneToOne;
|
||||
|
||||
public ManyToOne(Table table) {
|
||||
super(table);
|
||||
|
@ -52,8 +52,9 @@ public class ManyToOne extends ToOne {
|
|||
isLazy(),
|
||||
isUnwrapProxy(),
|
||||
isEmbedded(),
|
||||
isIgnoreNotFound()
|
||||
);
|
||||
isIgnoreNotFound(),
|
||||
isLogicalOneToOne
|
||||
);
|
||||
}
|
||||
|
||||
public void createForeignKey() throws MappingException {
|
||||
|
@ -110,5 +111,11 @@ public class ManyToOne extends ToOne {
|
|||
this.ignoreNotFound = ignoreNotFound;
|
||||
}
|
||||
|
||||
|
||||
public void markAsLogicalOneToOne() {
|
||||
this.isLogicalOneToOne = true;
|
||||
}
|
||||
|
||||
public boolean isLogicalOneToOne() {
|
||||
return isLogicalOneToOne;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,7 +20,6 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.tuple.entity;
|
||||
|
||||
|
@ -29,7 +28,6 @@ import java.util.Iterator;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.tuple.Instantiator;
|
||||
|
@ -132,12 +130,12 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
getters = new Getter[propertySpan];
|
||||
setters = new Setter[propertySpan];
|
||||
|
||||
Iterator iter = mappingInfo.getPropertyClosureIterator();
|
||||
Iterator itr = mappingInfo.getPropertyClosureIterator();
|
||||
boolean foundCustomAccessor=false;
|
||||
int i=0;
|
||||
while ( iter.hasNext() ) {
|
||||
while ( itr.hasNext() ) {
|
||||
//TODO: redesign how PropertyAccessors are acquired...
|
||||
Property property = (Property) iter.next();
|
||||
Property property = (Property) itr.next();
|
||||
getters[i] = buildPropertyGetter(property, mappingInfo);
|
||||
setters[i] = buildPropertySetter(property, mappingInfo);
|
||||
if ( !property.isBasicPropertyAccessor() ) {
|
||||
|
@ -172,7 +170,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
}
|
||||
|
||||
/**
|
||||
* Retreives the defined entity-names for any subclasses defined for this
|
||||
* Retrieves the defined entity-names for any subclasses defined for this
|
||||
* entity.
|
||||
*
|
||||
* @return Any subclass entity-names.
|
||||
|
@ -208,7 +206,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
catch ( ClassCastException cce ) {
|
||||
StringBuffer msg = new StringBuffer( "Identifier classes must be serializable. " );
|
||||
if ( id != null ) {
|
||||
msg.append( id.getClass().getName() + " is not serializable. " );
|
||||
msg.append( id.getClass().getName() ).append( " is not serializable. " );
|
||||
}
|
||||
if ( cce.getMessage() != null ) {
|
||||
msg.append( cce.getMessage() );
|
||||
|
@ -296,16 +294,21 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
}
|
||||
|
||||
public Object getPropertyValue(Object entity, String propertyPath) throws HibernateException {
|
||||
|
||||
int loc = propertyPath.indexOf('.');
|
||||
String basePropertyName = loc>0 ?
|
||||
propertyPath.substring(0, loc) : propertyPath;
|
||||
|
||||
int index = entityMetamodel.getPropertyIndex( basePropertyName );
|
||||
Object baseValue = getPropertyValue( entity, index );
|
||||
if ( loc>0 ) {
|
||||
ComponentType type = (ComponentType) entityMetamodel.getPropertyTypes()[index];
|
||||
return getComponentValue( type, baseValue, propertyPath.substring(loc+1) );
|
||||
final int loc = propertyPath.indexOf('.');
|
||||
final String basePropertyName = loc > 0
|
||||
? propertyPath.substring( 0, loc )
|
||||
: propertyPath;
|
||||
final int index = entityMetamodel.getPropertyIndex( basePropertyName );
|
||||
final Object baseValue = getPropertyValue( entity, index );
|
||||
if ( loc > 0 ) {
|
||||
if ( baseValue == null ) {
|
||||
return null;
|
||||
}
|
||||
return getComponentValue(
|
||||
(ComponentType) entityMetamodel.getPropertyTypes()[index],
|
||||
baseValue,
|
||||
propertyPath.substring(loc+1)
|
||||
);
|
||||
}
|
||||
else {
|
||||
return baseValue;
|
||||
|
@ -321,25 +324,21 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
* @return The property value extracted.
|
||||
*/
|
||||
protected Object getComponentValue(ComponentType type, Object component, String propertyPath) {
|
||||
|
||||
int loc = propertyPath.indexOf('.');
|
||||
String basePropertyName = loc>0 ?
|
||||
propertyPath.substring(0, loc) : propertyPath;
|
||||
|
||||
String[] propertyNames = type.getPropertyNames();
|
||||
int index=0;
|
||||
for ( ; index<propertyNames.length; index++ ) {
|
||||
if ( basePropertyName.equals( propertyNames[index] ) ) break;
|
||||
}
|
||||
if (index==propertyNames.length) {
|
||||
throw new MappingException( "component property not found: " + basePropertyName );
|
||||
}
|
||||
|
||||
Object baseValue = type.getPropertyValue( component, index, getEntityMode() );
|
||||
|
||||
if ( loc>0 ) {
|
||||
ComponentType subtype = (ComponentType) type.getSubtypes()[index];
|
||||
return getComponentValue( subtype, baseValue, propertyPath.substring(loc+1) );
|
||||
final int loc = propertyPath.indexOf( '.' );
|
||||
final String basePropertyName = loc > 0
|
||||
? propertyPath.substring( 0, loc )
|
||||
: propertyPath;
|
||||
final int index = findSubPropertyIndex( type, basePropertyName );
|
||||
final Object baseValue = type.getPropertyValue( component, index, getEntityMode() );
|
||||
if ( loc > 0 ) {
|
||||
if ( baseValue == null ) {
|
||||
return null;
|
||||
}
|
||||
return getComponentValue(
|
||||
(ComponentType) type.getSubtypes()[index],
|
||||
baseValue,
|
||||
propertyPath.substring(loc+1)
|
||||
);
|
||||
}
|
||||
else {
|
||||
return baseValue;
|
||||
|
@ -347,6 +346,16 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
|||
|
||||
}
|
||||
|
||||
private int findSubPropertyIndex(ComponentType type, String subPropertyName) {
|
||||
final String[] propertyNames = type.getPropertyNames();
|
||||
for ( int index = 0; index<propertyNames.length; index++ ) {
|
||||
if ( subPropertyName.equals( propertyNames[index] ) ) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
throw new MappingException( "component property not found: " + subPropertyName );
|
||||
}
|
||||
|
||||
public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
|
||||
boolean setAll = !entityMetamodel.hasLazyProperties();
|
||||
|
||||
|
|
|
@ -508,8 +508,22 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the association modeled here defined as a 1-1 in the database (physical model)?
|
||||
*
|
||||
* @return True if a 1-1 in the database; false otherwise.
|
||||
*/
|
||||
public abstract boolean isOneToOne();
|
||||
|
||||
/**
|
||||
* Is the association modeled here a 1-1 according to the logical moidel?
|
||||
*
|
||||
* @return True if a 1-1 in the logical model; false otherwise.
|
||||
*/
|
||||
public boolean isLogicalOneToOne() {
|
||||
return isOneToOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to locate the identifier type of the associated entity.
|
||||
*
|
||||
|
|
|
@ -45,27 +45,54 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class ManyToOneType extends EntityType {
|
||||
|
||||
private final boolean ignoreNotFound;
|
||||
private boolean isLogicalOneToOne;
|
||||
|
||||
public ManyToOneType(String className) {
|
||||
this( className, false );
|
||||
/**
|
||||
* Creates a many-to-one association type with the given referenced entity.
|
||||
*
|
||||
* @param referencedEntityName The name iof the referenced entity
|
||||
*/
|
||||
public ManyToOneType(String referencedEntityName) {
|
||||
this( referencedEntityName, false );
|
||||
}
|
||||
|
||||
public ManyToOneType(String className, boolean lazy) {
|
||||
super( className, null, !lazy, true, false );
|
||||
this.ignoreNotFound = false;
|
||||
/**
|
||||
* Creates a many-to-one association type with the given referenced entity and the
|
||||
* given laziness characteristic
|
||||
*
|
||||
* @param referencedEntityName The name iof the referenced entity
|
||||
* @param lazy Should the association be handled lazily
|
||||
*/
|
||||
public ManyToOneType(String referencedEntityName, boolean lazy) {
|
||||
this( referencedEntityName, null, !lazy, true, false, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #ManyToOneType(String, String, boolean, boolean, boolean, boolean, boolean)}
|
||||
* @noinspection JavaDoc
|
||||
*/
|
||||
public ManyToOneType(
|
||||
String entityName,
|
||||
String referencedEntityName,
|
||||
String uniqueKeyPropertyName,
|
||||
boolean lazy,
|
||||
boolean unwrapProxy,
|
||||
boolean isEmbeddedInXML,
|
||||
boolean ignoreNotFound) {
|
||||
super( entityName, uniqueKeyPropertyName, !lazy, isEmbeddedInXML, unwrapProxy );
|
||||
this( referencedEntityName, uniqueKeyPropertyName, !lazy, isEmbeddedInXML, unwrapProxy, ignoreNotFound, false );
|
||||
}
|
||||
|
||||
public ManyToOneType(
|
||||
String referencedEntityName,
|
||||
String uniqueKeyPropertyName,
|
||||
boolean lazy,
|
||||
boolean unwrapProxy,
|
||||
boolean isEmbeddedInXML,
|
||||
boolean ignoreNotFound,
|
||||
boolean isLogicalOneToOne) {
|
||||
super( referencedEntityName, uniqueKeyPropertyName, !lazy, isEmbeddedInXML, unwrapProxy );
|
||||
this.ignoreNotFound = ignoreNotFound;
|
||||
this.isLogicalOneToOne = isLogicalOneToOne;
|
||||
}
|
||||
|
||||
protected boolean isNullable() {
|
||||
|
@ -82,7 +109,11 @@ public class ManyToOneType extends EntityType {
|
|||
public boolean isOneToOne() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean isLogicalOneToOne() {
|
||||
return isLogicalOneToOne;
|
||||
}
|
||||
|
||||
public int getColumnSpan(Mapping mapping) throws MappingException {
|
||||
// our column span is the number of columns in the PK
|
||||
return getIdentifierOrUniqueKeyType( mapping ).getColumnSpan( mapping );
|
||||
|
|
|
@ -201,6 +201,8 @@ public final class TypeFactory {
|
|||
|
||||
/**
|
||||
* A many-to-one association type for the given class
|
||||
*
|
||||
* @deprecated Use {@link #manyToOne(String, String, boolean, boolean, boolean, boolean, boolean)}
|
||||
*/
|
||||
public static EntityType manyToOne(
|
||||
String persistentClass,
|
||||
|
@ -208,8 +210,8 @@ public final class TypeFactory {
|
|||
boolean lazy,
|
||||
boolean unwrapProxy,
|
||||
boolean isEmbeddedInXML,
|
||||
boolean ignoreNotFound
|
||||
) {
|
||||
boolean ignoreNotFound) {
|
||||
//noinspection deprecation
|
||||
return new ManyToOneType(
|
||||
persistentClass,
|
||||
uniqueKeyPropertyName,
|
||||
|
@ -217,7 +219,29 @@ public final class TypeFactory {
|
|||
unwrapProxy,
|
||||
isEmbeddedInXML,
|
||||
ignoreNotFound
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A many-to-one association type for the given class
|
||||
*/
|
||||
public static EntityType manyToOne(
|
||||
String persistentClass,
|
||||
String uniqueKeyPropertyName,
|
||||
boolean lazy,
|
||||
boolean unwrapProxy,
|
||||
boolean isEmbeddedInXML,
|
||||
boolean ignoreNotFound,
|
||||
boolean isLogicalOneToOne) {
|
||||
return new ManyToOneType(
|
||||
persistentClass,
|
||||
uniqueKeyPropertyName,
|
||||
lazy,
|
||||
unwrapProxy,
|
||||
isEmbeddedInXML,
|
||||
ignoreNotFound,
|
||||
isLogicalOneToOne
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -629,6 +629,10 @@ public class CustomPersister implements EntityPersister {
|
|||
return false;
|
||||
}
|
||||
|
||||
public String[] getOrphanRemovalOneToOnePaths() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session) throws HibernateException {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.orphan.one2one.fk.reversed.bidirectional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.junit.functional.FunctionalTestCase;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DeleteOneToOneOrphansTest extends FunctionalTestCase {
|
||||
public DeleteOneToOneOrphansTest(String string) {
|
||||
super( string );
|
||||
}
|
||||
|
||||
public String[] getMappings() {
|
||||
return new String[] { "orphan/one2one/fk/reversed/bidirectional/Mapping.hbm.xml" };
|
||||
}
|
||||
|
||||
private void createData() {
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
Employee emp = new Employee();
|
||||
emp.setInfo( new EmployeeInfo( emp ) );
|
||||
session.save( emp );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
private void cleanupData() {
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
session.createQuery( "delete EmployeeInfo" ).executeUpdate();
|
||||
session.createQuery( "delete Employee" ).executeUpdate();
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
public void testOrphanedWhileManaged() {
|
||||
createData();
|
||||
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
List results = session.createQuery( "from EmployeeInfo" ).list();
|
||||
assertEquals( 1, results.size() );
|
||||
results = session.createQuery( "from Employee" ).list();
|
||||
assertEquals( 1, results.size() );
|
||||
Employee emp = ( Employee ) results.get( 0 );
|
||||
assertNotNull( emp.getInfo() );
|
||||
emp.setInfo( null );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
emp = ( Employee ) session.get( Employee.class, emp.getId() );
|
||||
assertNull( emp.getInfo() );
|
||||
results = session.createQuery( "from EmployeeInfo" ).list();
|
||||
assertEquals( 0, results.size() );
|
||||
results = session.createQuery( "from Employee" ).list();
|
||||
assertEquals( 1, results.size() );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
cleanupData();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.orphan.one2one.fk.reversed.bidirectional;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Employee {
|
||||
private Long id;
|
||||
private EmployeeInfo info;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public EmployeeInfo getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void setInfo(EmployeeInfo info) {
|
||||
this.info = info;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.orphan.one2one.fk.reversed.bidirectional;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EmployeeInfo {
|
||||
private Long id;
|
||||
private Employee employee;
|
||||
|
||||
public EmployeeInfo() {
|
||||
}
|
||||
|
||||
public EmployeeInfo(Employee employee) {
|
||||
this.employee = employee;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Employee getEmployee() {
|
||||
return employee;
|
||||
}
|
||||
|
||||
public void setEmployee(Employee employee) {
|
||||
this.employee = employee;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Inc.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
|
||||
<!DOCTYPE hibernate-mapping PUBLIC
|
||||
'-//Hibernate/Hibernate Mapping DTD 3.0//EN'
|
||||
'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'>
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.orphan.one2one.fk.reversed.bidirectional" >
|
||||
|
||||
<class name="Employee">
|
||||
<id name="id" type="long" column="id">
|
||||
<generator class="increment" />
|
||||
</id>
|
||||
<many-to-one name="info"
|
||||
column="info_id"
|
||||
unique="true"
|
||||
cascade="all,delete-orphan"/>
|
||||
</class>
|
||||
|
||||
<class name="EmployeeInfo">
|
||||
<id name="id" type="long" column="id">
|
||||
<generator class="increment" />
|
||||
</id>
|
||||
<one-to-one name="employee"
|
||||
property-ref="info"
|
||||
class="Employee" />
|
||||
</class>
|
||||
|
||||
</hibernate-mapping>
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.orphan.one2one.fk.reversed.unidirectional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.junit.functional.FunctionalTestCase;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DeleteOneToOneOrphansTest extends FunctionalTestCase {
|
||||
public DeleteOneToOneOrphansTest(String string) {
|
||||
super( string );
|
||||
}
|
||||
|
||||
public String[] getMappings() {
|
||||
return new String[] { "orphan/one2one/fk/reversed/unidirectional/Mapping.hbm.xml" };
|
||||
}
|
||||
|
||||
private void createData() {
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
Employee emp = new Employee();
|
||||
emp.setInfo( new EmployeeInfo() );
|
||||
session.save( emp );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
private void cleanupData() {
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
session.createQuery( "delete EmployeeInfo" ).executeUpdate();
|
||||
session.createQuery( "delete Employee" ).executeUpdate();
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
}
|
||||
|
||||
public void testOrphanedWhileManaged() {
|
||||
createData();
|
||||
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
List results = session.createQuery( "from EmployeeInfo" ).list();
|
||||
assertEquals( 1, results.size() );
|
||||
results = session.createQuery( "from Employee" ).list();
|
||||
assertEquals( 1, results.size() );
|
||||
Employee emp = ( Employee ) results.get( 0 );
|
||||
assertNotNull( emp.getInfo() );
|
||||
emp.setInfo( null );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
emp = ( Employee ) session.get( Employee.class, emp.getId() );
|
||||
assertNull( emp.getInfo() );
|
||||
results = session.createQuery( "from EmployeeInfo" ).list();
|
||||
assertEquals( 0, results.size() );
|
||||
results = session.createQuery( "from Employee" ).list();
|
||||
assertEquals( 1, results.size() );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
cleanupData();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.orphan.one2one.fk.reversed.unidirectional;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class Employee {
|
||||
private Long id;
|
||||
private EmployeeInfo info;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public EmployeeInfo getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void setInfo(EmployeeInfo info) {
|
||||
this.info = info;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.orphan.one2one.fk.reversed.unidirectional;
|
||||
|
||||
/**
|
||||
* TODO : javadoc
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EmployeeInfo {
|
||||
private Long id;
|
||||
|
||||
public EmployeeInfo() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Inc.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
~ Lesser General Public License, as published by the Free Software Foundation.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
~ for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Lesser General Public License
|
||||
~ along with this distribution; if not, write to:
|
||||
~ Free Software Foundation, Inc.
|
||||
~ 51 Franklin Street, Fifth Floor
|
||||
~ Boston, MA 02110-1301 USA
|
||||
-->
|
||||
|
||||
<!DOCTYPE hibernate-mapping PUBLIC
|
||||
'-//Hibernate/Hibernate Mapping DTD 3.0//EN'
|
||||
'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'>
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.orphan.one2one.fk.reversed.unidirectional" >
|
||||
|
||||
<class name="Employee">
|
||||
<id name="id" type="long" column="id">
|
||||
<generator class="increment" />
|
||||
</id>
|
||||
<many-to-one name="info"
|
||||
column="info_id"
|
||||
unique="true"
|
||||
cascade="all,delete-orphan"/>
|
||||
</class>
|
||||
|
||||
<class name="EmployeeInfo">
|
||||
<id name="id" type="long" column="id">
|
||||
<generator class="increment" />
|
||||
</id>
|
||||
</class>
|
||||
|
||||
</hibernate-mapping>
|
Loading…
Reference in New Issue