-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: hbm2java: how to change field names/class references
PostPosted: Tue Dec 23, 2008 5:12 am 
Newbie

Joined: Tue Dec 23, 2008 5:04 am
Posts: 3
Hi,

I'm struggling with a problem trying to reverse engineer a MySQL database using hbm2java (indirectly by using seam-gen generate-model).

The tables in the database are named t_ prefix, and this results in some unwanted naming problems (similar problems discussed elsewhere in this forum).

The problem is that when running "seam generate" the entities and the session beans and the JSF pages are generated I get a "property xxx not found on type..." exception.

After investigating this, it turns out that I can make it work by manually editing the session and entity beans, by changing the getXFoo() methods to getxFoo(). Same with set methods.

What I am trying to do instead of editing the generated classes, is to understand and change the way the java classes are generated, and that's the reason I ask this question in this forum, and not in a seam forum.

I want to totally remove the t_ prefix in the generated classes.

By editing the reveng.xml to rename my generated classes, I get the result I want in regard to the class names:

Code:
<hibernate-reverse-engineering>
   <table-filter match-name="t_customer">
      <meta attribute="generated-class">foo.bar.entity.Customer</meta>
   </table-filter>
   <table-filter match-name="t_customer_group">
      <meta attribute="generated-class">foo.bar.entity.CustomerGroup</meta>
   </table-filter>
</hibernate-reverse-engineering>

this results in a generated class Customer and CustomerGroup.

The problem is that CustomerGroup is having having a reference to TCustomer in a field named TCustomer:
Code:
public class CustomerGroup implements java.io.Serializable {

   private TCustomer TCustomer;

   public TCustomer getTCustomer() {
      return this.TCustomer;
   }

   public void setTCustomer(TCustomer TCustomer) {
      this.TCustomer = TCustomer;
   }

and Customer holds a field named TCustomerGroups:
Code:
public class Customer implements java.io.Serializable {

   private Set<TCustomerGroup> TCustomerGroups = new HashSet<TCustomerGroup>(0);

   public Set<TCustomerGroup> getTCustomerGroups() {
      return this.TCustomerGroups;
   }

   public void setTCustomerGroups(Set<TCustomerGroup> TCustomerGroups) {
      this.TCustomerGroups = TCustomerGroups;
   }


As a result I get set and get methods on the form setXFoo.

What I would like is to have the following result:

Code:
public class CustomerGroup implements java.io.Serializable {

   private Customer customer;

   public Customer getCustomer() {
      return this.customer;
   }

   public void setCustomer(Customer customer) {
      this.customer = customer;
   }

and same thing for CustomerGroup.

Here's the question:

Where/How do I modify the generation of the java source files to work as I describe above (not only change class names, but also field names, set/get and class references).

Is it possible to do in reveng.xml, or do I need to modify a template or something eles?

Thanks!

/Marcus


Top
 Profile  
 
 Post subject: any feedback at all
PostPosted: Mon Dec 29, 2008 7:10 am 
Newbie

Joined: Tue Dec 23, 2008 5:04 am
Posts: 3
Does anyone have any kind of feedback on my question?

Is this a RTFM issue (what FM in that case?) or do I need to add more info to make it easier to understand my problem? I really would appreciate any pointer in a good direction, and I will gladly read through any documentation (no need for full explanation at all) as long as I know where it is described.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 31, 2008 4:24 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
Dude, it's christmas - don't expect answers immediately ;)

Use a custom ReverseEngineeringStrategy which implements tableToClassName which cuts of the first "t_"

There you go, and Merry Christmas ;)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 31, 2008 5:29 am 
Newbie

Joined: Tue Dec 23, 2008 5:04 am
Posts: 3
max wrote:
Dude, it's christmas - don't expect answers immediately ;)

Use a custom ReverseEngineeringStrategy which implements tableToClassName which cuts of the first "t_"

There you go, and Merry Christmas ;)


hehehe, sorry for being so eager :)

I actually fixed it yesterday and thought I'd explain how, but you were faster than me. I used the following resources I found by Googling:



Here's how I did:

1. I packed a single class named foo.bar.MyReverseEngineeringStrategy (code below) in a jar file named MyReverseEngineeringStrategy.jar

2. I put the jar in <jboss-seam-root>\lib

3. I edited the file <jboss-seam-root>\lib\seam-gen\build.xml in two places:

3a. First add the jar:

<target name="init-generate">
<path id="htools.classpath">
<pathelement path="${seam.dir}/lib/gen/jboss-seam-gen.jar"/>
...
<pathelement path="${seam.dir}/lib/MyReverseEngineeringStrategy.jar"/>

3b. Then add my custom reversestrategy class:

<jdbcconfiguration propertyfile="${seam-gen.properties}"
packagename="${model.package}"
revengfile="${project.home}/resources/seam-gen.reveng.xml"
reversestrategy="foo.bar.MyReverseEngineeringStrategy"

4. Then I ran seam generate

Works like a charm! I do not need to change anything in reveng.xml using this strategy.

Here's the code. I have not tried to make it fancy in any way, just do the work. The code is not performance critical as it's used very seldom anyway.

Code:
package foo.bar;

import java.util.List;

import org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.TableIdentifier;
import org.hibernate.mapping.ForeignKey;

public class MyReverseEngineeringStrategy extends
      DelegatingReverseEngineeringStrategy {

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

   public String foreignKeyToManyToManyName(ForeignKey fromKey,
         TableIdentifier middleTable, ForeignKey toKey,
         boolean uniqueReference) {
      String defaultName = super.foreignKeyToManyToManyName(fromKey,
            middleTable, toKey, uniqueReference);
      String firstChar = defaultName.toLowerCase().substring(0, 1);
      return firstChar + defaultName.substring(1);
   }

   @SuppressWarnings("unchecked")
   public String foreignKeyToEntityName(String keyname,
         TableIdentifier fromTable, List fromColumnNames,
         TableIdentifier referencedTable, List referencedColumnNames,
         boolean uniqueReference) {
      String defaultName = (String) super.foreignKeyToEntityName(keyname,
            fromTable, fromColumnNames, referencedTable,
            referencedColumnNames, uniqueReference);
      String firstChar = defaultName.toLowerCase().substring(0, 1);
      return firstChar + defaultName.substring(1);
   }

   @SuppressWarnings("unchecked")
   public String foreignKeyToCollectionName(String keyname,
         TableIdentifier fromTable, List fromColumns,
         TableIdentifier referencedTable, List referencedColumns,
         boolean uniqueReference) {
      String defaultName = super.foreignKeyToCollectionName(keyname,
            fromTable, fromColumns, referencedTable, referencedColumns,
            uniqueReference);
      String firstChar = defaultName.toLowerCase().substring(0, 1);
      return firstChar + defaultName.substring(1);
   }

   public String tableToClassName(TableIdentifier tableIdentifier) {
      String defaultName = super.tableToClassName(tableIdentifier);
      String tableName = tableIdentifier.getName();
      if (tableName.startsWith("t_")) {
         int idx = defaultName.lastIndexOf(".");
         String className = defaultName.substring(idx + 2);
         String packageName = defaultName.substring(0, (idx + 1));
         return packageName + className;
      }
      return defaultName;
   }
}


Thanks for the reply, and a Happy New Year :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.