Problem with reverse engineering a many-to-one unidirectional association with hibernate tools
Asked Answered
G

2

6


I'm using Hibernate tools 3.40 in Eclipse (Helios). I'm trying to generate POJOs from my DB (MSSQL 2008) with EJB3 style (i.e. JPA2.0 annotations).
Let's say I have two tables A and B where there is a foreign key from A to B.
This generates, by default, a POJO for A which has B as a member (its "parent") and a POJO for B which has a Set<A> as a member (its "children").
What I'd like is to know how I can control the rev-eng so that only one side of the association is created (I have different use cases so basically all three options are important for me).
I do not want to use hbm.xml files as I'm working with annotations and JPA2.0 but I can specify some metadata on the reverse engineering process to hibernate via hibernae.reveng.xml

I've tried configuring the foreign-key attribute and defining there the exclude=true but that only provided me with a half an answer for one scenario. That generated an A POJO with a bPK int member which is tolerable and understandable but the generated POJO of B now does not compile as the one-to-many annotation has an invalid attribute; The mappedby="unresolved" due to the fact that A no longer has a property which hibernate reveng can map back to.

So, I currently cannot create uni-directional associations and I'd appreciate any help.

Gotland answered 9/3, 2011 at 14:7 Comment(0)
R
4

Create a class for reveng. strategy at Hibernate Code Generation Configuration

Example :

public class MyReverseEngineeringStrategy extends DelegatingReverseEngineeringStrategy {

   public MyReverseEngineeringStrategy(ReverseEngineeringStrategy delegate) {
       super(delegate);
   }

   @Override
   public void setSettings(ReverseEngineeringSettings settings) {
       super.setSettings(settings);
   }

   @Override
   public boolean excludeForeignKeyAsCollection(String keyname, 
    TableIdentifier fromTable, java.util.List fromColumns, 
    TableIdentifier referencedTable, java.util.List referencedColumns) {

    // TODO : Your work here
    if (keyname.equals("___") && 
        fromTable.getName().equals("___") && 
        fromColumns.contains("___") && 
        referencedTable.getName().equals("___") && 
        referencedColumns.contains("___")) {

        return true;
    }

    return false;
   }
}

JavaDoc for method excludeForeignKeyAsCollection

Should this foreignkey be excluded as a oneToMany 

and there also have another method call excludeForeignKeyAsManytoOne

Should this foreignkey be excluded as a many-to-one 
Relay answered 11/3, 2011 at 5:34 Comment(2)
Thanks a lot. I wish there was a better way to do this than to hardcode these requirements in that "obscure" class but at least it's a working solution.Gotland
I have the same problem, but your answer is specific for the "___", it is not a general answer. Thanks anywayDotation
D
1

Currently (tested with Hibernate Tools 5.2), generating unidirectional many-to-one works.

In the documentation (https://docs.jboss.org/tools/4.0.0.Final/en/hibernatetools/html_single/index.html#hibernaterevengxmlfile), you can see that you can exclude some side of the relationship :

For example (renaming properties)

 <!-- control many-to-one and set names for a specific named foreign key constraint -->
 <foreign-key constraint-name="ORDER_CUST">
   <many-to-one property="customer"/>
   <set property="orders"/>
 </foreign-key>

Or (excluding properties)

 <!-- can also control a pure (shared pk) one-to-one  -->
  <foreign-key constraint-name="ADDRESS_PERSON">
   <one-to-one exclude="false"/>
   <inverse-one-to-one exclude="true"/>
  </foreign-key>

So to have just one side of the relationship with @ManyToOne only, you could do the following :

<table name="city" schema="public">
    <primary-key property="id">
        <key-column name="id" type="integer"/>
    </primary-key>
</table>

<table name="country" schema="public">
    <foreign-key constraint-name="country_capital_fkey" foreign-schema="public">
        <many-to-one property="capital" exclude="false"/>
        <set exclude="true" />
    </foreign-key>
</table>

You can also fetch an instance of my sample database with Docker here :

docker pull ghusta/postgres-world-db:2.1

Dolan answered 23/6, 2017 at 10:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.