diff --git a/core/src/main/java/org/hibernate/cfg/HbmBinder.java b/core/src/main/java/org/hibernate/cfg/HbmBinder.java index 42ab755189..372ba86a5a 100644 --- a/core/src/main/java/org/hibernate/cfg/HbmBinder.java +++ b/core/src/main/java/org/hibernate/cfg/HbmBinder.java @@ -1101,6 +1101,16 @@ public final class HbmBinder { simpleValue.addFormula( formula ); } } + + // todo : another GoodThing would be to go back after all parsing and see if all the columns + // (and no formulas) are contained in a defined unique key that only contains these columns. + // That too would mark this as a logical one-to-one + final Attribute uniqueAttribute = node.attribute( "unique" ); + if ( uniqueAttribute != null + && "true".equals( uniqueAttribute.getValue() ) + && ManyToOne.class.isInstance( simpleValue ) ) { + ( (ManyToOne) simpleValue ).markAsLogicalOneToOne(); + } } else { if ( node.elementIterator( "column" ).hasNext() ) { diff --git a/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/DeleteOneToOneOrphansTest.java b/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/DeleteOneToOneOrphansTest.java new file mode 100644 index 0000000000..c7c8debef5 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/DeleteOneToOneOrphansTest.java @@ -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.composite; + +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/composite/Mapping.hbm.xml" }; + } + + private void createData() { + Session session = openSession(); + session.beginTransaction(); + Employee emp = new Employee(); + emp.setInfo( new EmployeeInfo( 1L, 1L) ); + 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(); + } +} \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/Employee.java b/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/Employee.java new file mode 100644 index 0000000000..bce3d257aa --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/Employee.java @@ -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.composite; + +/** + * 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; + } +} \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/EmployeeInfo.java b/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/EmployeeInfo.java new file mode 100644 index 0000000000..53047b9d9a --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/EmployeeInfo.java @@ -0,0 +1,106 @@ +/* + * 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.composite; + +import java.io.Serializable; + +/** + * TODO : javadoc + * + * @author Steve Ebersole + */ +public class EmployeeInfo { + public static class Id implements Serializable { + private Long companyId; + private Long personId; + + public Id() { + } + + public Id(Long companyId, Long personId) { + this.companyId = companyId; + this.personId = personId; + } + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } + + public Long getPersonId() { + return personId; + } + + public void setPersonId(Long personId) { + this.personId = personId; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + Id id = (Id) o; + + return companyId.equals( id.companyId ) + && personId.equals( id.personId ); + + } + + @Override + public int hashCode() { + int result = companyId.hashCode(); + result = 31 * result + personId.hashCode(); + return result; + } + } + + private Id id; + + public EmployeeInfo() { + } + + public EmployeeInfo(Long companyId, Long personId) { + this( new Id( companyId, personId ) ); + } + + public EmployeeInfo(Id id) { + this.id = id; + } + + public Id getId() { + return id; + } + + public void setId(Id id) { + this.id = id; + } +} \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/Mapping.hbm.xml b/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/Mapping.hbm.xml new file mode 100644 index 0000000000..3a3733728d --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/orphan/one2one/fk/composite/Mapping.hbm.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + +