diff --git a/annotations/src/main/java/org/hibernate/cfg/ColumnsBuilder.java b/annotations/src/main/java/org/hibernate/cfg/ColumnsBuilder.java index 8b34f0f4df..d2aaae488b 100644 --- a/annotations/src/main/java/org/hibernate/cfg/ColumnsBuilder.java +++ b/annotations/src/main/java/org/hibernate/cfg/ColumnsBuilder.java @@ -15,6 +15,7 @@ import org.hibernate.annotations.CollectionOfElements; import org.hibernate.annotations.Columns; import org.hibernate.annotations.Formula; import org.hibernate.annotations.JoinColumnsOrFormulas; +import org.hibernate.annotations.JoinFormula; import org.hibernate.annotations.common.reflection.XProperty; import org.hibernate.cfg.annotations.EntityBinder; import org.hibernate.cfg.annotations.Nullability; @@ -177,6 +178,13 @@ class ColumnsBuilder { propertyHolder, inferredData.getPropertyName(), mappings ); } + else if (property.isAnnotationPresent( JoinFormula.class)) { + JoinFormula ann = property.getAnnotation( JoinFormula.class ); + joinColumns = new Ejb3JoinColumn[1]; + joinColumns[0] = Ejb3JoinColumn.buildJoinFormula( + ann, null, entityBinder.getSecondaryTables(), + propertyHolder, inferredData.getPropertyName(), mappings); + } } return joinColumns; } diff --git a/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java b/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java index f67069eb1d..f5652c07ec 100644 --- a/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java +++ b/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java @@ -165,7 +165,7 @@ public class Ejb3JoinColumn extends Ejb3Column { /** * build join formula */ - private static Ejb3JoinColumn buildJoinFormula( + public static Ejb3JoinColumn buildJoinFormula( JoinFormula ann, String mappedBy, Map joins, PropertyHolder propertyHolder, diff --git a/annotations/src/test/java/org/hibernate/test/annotations/manytoonewithformula/ManyToOneWithFormulaTest.java b/annotations/src/test/java/org/hibernate/test/annotations/manytoonewithformula/ManyToOneWithFormulaTest.java index 521ae93f6b..5be88ee2ae 100644 --- a/annotations/src/test/java/org/hibernate/test/annotations/manytoonewithformula/ManyToOneWithFormulaTest.java +++ b/annotations/src/test/java/org/hibernate/test/annotations/manytoonewithformula/ManyToOneWithFormulaTest.java @@ -149,6 +149,45 @@ public class ManyToOneWithFormulaTest extends TestCase { } + /** + * This method also tests usage of the stand-alone @JoinFormula annotation (i.e. not wrapped within @JoinColumnsOrFormulas) + */ + @SkipForDialect(value = { HSQLDialect.class }, comment = "The used join conditions does not work in HSQLDB. See HHH-4497") + public void testManyToOneFromNonPkToNonPk() throws Exception + { + + Session s = openSession(); + Transaction tx = s.beginTransaction(); + + Product kit = new Product(); + kit.id = 1; + kit.productIdnf = "KIT"; + kit.description = "Kit"; + s.persist(kit); + + Product kitkat = new Product(); + kitkat.id = 2; + kitkat.productIdnf = "KIT_KAT"; + kitkat.description = "Chocolate"; + s.persist(kitkat); + + s.flush(); + s.clear(); + + kit = (Product) s.get(Product.class, 1); + kitkat = (Product) s.get(Product.class, 2); + System.out.println(kitkat.description); + assertNotNull(kitkat); + assertEquals(kit, kitkat.getProductFamily()); + assertEquals(kit.productIdnf, kitkat.getProductFamily().productIdnf); + assertEquals("KIT_KAT", kitkat.productIdnf.trim()); + assertEquals("Chocolate", kitkat.description.trim()); + + tx.rollback(); + s.close(); + } + + /** * @see org.hibernate.test.annotations.TestCase#getAnnotatedClasses() */ @@ -165,7 +204,8 @@ public class ManyToOneWithFormulaTest extends TestCase { Model.class, ModelId.class, Manufacturer.class, - ManufacturerId.class + ManufacturerId.class, + Product.class }; } diff --git a/annotations/src/test/java/org/hibernate/test/annotations/manytoonewithformula/Product.java b/annotations/src/test/java/org/hibernate/test/annotations/manytoonewithformula/Product.java new file mode 100644 index 0000000000..a2f82df5c7 --- /dev/null +++ b/annotations/src/test/java/org/hibernate/test/annotations/manytoonewithformula/Product.java @@ -0,0 +1,74 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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.annotations.manytoonewithformula; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; +import org.hibernate.annotations.JoinFormula; + +/** + * @author Sharath Reddy + * + */ +@Entity +@Table(name="product") +public class Product implements Serializable +{ + + private static final long serialVersionUID = 6956478993159505828L; + + @Id + public Integer id; + + @Column(name="product_idnf", length=18, nullable=false, unique=true, + columnDefinition="char(18)") + public String productIdnf; + + @Column(name="description", nullable=false) + public String description; + + @ManyToOne + @JoinFormula(value="SUBSTR(product_idnf, 1, 3)", + referencedColumnName="product_idnf") + @Fetch(FetchMode.JOIN) + private Product productFamily; + + public Product getProductFamily() + { + return productFamily; + } + +}