Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Avoid generating primary key column in minimal constructor
PostPosted: Thu Dec 06, 2007 6:10 am 
Newbie

Joined: Tue Nov 06, 2007 4:37 am
Posts: 1
Location: Germany
Hi,

I don't want to have my primary key column in the minimal constructor. Is there a simple way to do this?

I found a complicated way, by overriding the POJOExporter and wrapping the POJOClass, but this is mayby not the best solution, I think.



Another question:

The order of the parameters in the minimal construcor seems to have changed between the current Hibernate Tools 3.2.0cr1 and the older one I used (3.2.0 beta 7).
How is the order determined? Is there a possibility to customize the order?


Thanks in advance


Top
 Profile  
 
 Post subject: Re: Avoid generating primary key column in minimal constructor
PostPosted: Fri Apr 20, 2012 4:47 am 
Newbie

Joined: Wed Apr 18, 2012 4:37 am
Posts: 7
I found a very dirty solution, that I would not recommend, but it works for me.
I changed the template PojoConstructors.ftl to remove any parameter from the constructor, that ends with "id".
But just think about a parameter named "stupid" - this would not show in the constructor, allthough it may not be an Id.

So... in my case I have to make sure, that no table column name ends with "id".

For this purpose, I defined the following macro within PojoConstructors.ftl:
Code:
<#--  /** returns the list of parameters seperated by comma, but without the id parameter */ -->
<#macro removeIdParam paramString>
<#list paramString?split(",") as x><#if !x?ends_with("id")>${x}<#if x_has_next>,</#if></#if></#list>
</#macro>


Then later on, I call:
Code:
<#if pojo.needsMinimalConstructor()>   <#-- /** minimal constructor */ -->
     /**
     * minimal constructor.
     *     
<#foreach field in pojo.getPropertiesForMinimalConstructor()><#if !field.name?ends_with("id")>
     * @param ${field.name}
</#foreach>     */
<#-- /** remove id parameter from constructor */-->
<#if c2j.asParameterList(pojo.getPropertyClosureForMinimalConstructor(), jdk5, pojo).contains("Id")>
//Id is removed
public Abstract${pojo.getDeclarationName()}(<@removeIdParam paramString=c2j.asParameterList(pojo.getPropertyClosureForMinimalConstructor(), jdk5, pojo)/>) {
<#else>
//no Id found
public Abstract${pojo.getDeclarationName()}(${c2j.asParameterList(pojo.getPropertyClosureForMinimalConstructor(), jdk5, pojo)}) {
</#if>
<#if pojo.isSubclass() && !pojo.getPropertyClosureForSuperclassMinimalConstructor().isEmpty()>
        super(${c2j.asArgumentList(pojo.getPropertyClosureForSuperclassMinimalConstructor())});       
</#if>
<#foreach field in pojo.getPropertiesForMinimalConstructor()>
<#if !field.name?ends_with("id")>     this.${field.name} = ${field.name};</#if>
</#foreach>
    }
</#if> 


It is a very dirty hack and I do not recommend doing it like this.


Top
 Profile  
 
 Post subject: Re: Avoid generating primary key column in minimal constructor
PostPosted: Fri Apr 20, 2012 11:01 am 
Senior
Senior

Joined: Fri May 08, 2009 12:27 pm
Posts: 168
You can always call the minimal constructor with a null for the id.
Why do you want to eliminate the id parameter?


Top
 Profile  
 
 Post subject: Re: Avoid generating primary key column in minimal constructor
PostPosted: Mon Apr 23, 2012 3:09 am 
Newbie

Joined: Wed Apr 18, 2012 4:37 am
Posts: 7
The reason in my case:
Because the code was originally generated without an Id parameter. In order to be compatible with the rest of the non-generated code, I need a constructor without the id parameter and I need the constructor with the parameters in the order that it had in the original version.

I also found out, that the change of order on parameters is due to a change of the JDK on handling HashMaps. This insight sadly does not help me in eliminating the problem.

Also: If you use the Eclipse plugin DTP for handling databases and you want to create the DDL script via "reverse engineering" feature, you get a totally different script, than originally used for creating the database.

Why is this bad? Because the order of columns makes a huge difference on performance in an Oracle database and affects my code generation using Hibernate reverse engineering.

Conclusion: As the JDK currently changes the order of columns when trying to obtain data from the database, it puts me in a situation, where I cannot rely on the JDK and I need to manually override the order somehow. This brings me back to my original question: Is there a way to manually override/configure hibernate to use a certain order for the columns instead of the ones gained via JDK/OJDBC? Any help is appreciated.

See also my post for the problem concerning order of parameters in a constructor on code generation:
viewtopic.php?f=1&t=1015226


Top
 Profile  
 
 Post subject: Re: Avoid generating primary key column in minimal constructor
PostPosted: Mon Apr 23, 2012 6:37 am 
Senior
Senior

Joined: Fri May 08, 2009 12:27 pm
Posts: 168
I've been finding the generated constructors rather useless.
Change the data model and you need to revisit each and any constructor call because there's another field that needs to be initialized - and there are no guarantees on the parameter order (as you just found out).
Note that hashmap order might change whenever you switch JVMs. It usually does when changing architecture. 32 vs. 64 bit gives most trouble; if you have a JDK with assembler-optimized hash codes you might also get into trouble with big-endian vs. little-endian, or even with i86 vs. ARM vs. whatever.

Ways out:

1) Rearrange the code to never ever use any constructor but the minimal one (plus setters to get the fields initialized).

2) Rewrite the template so that parameters are sorted, by name (since the code generation does not have the database order available, and database order isn't necessarily stable anyway).

Ways 1 and 2 require that you'll have one rewrite both of your and the foreign code. You don't need to do that more than once.

3) Do not use reveng as part of the normal build process. Use it only for an initial sketch of the entity class. You retain control of the constructor parameter order that way, and make sure it never changes.

4) Change the templates so that they generate a superclass but tell Hibernate to use a subclass. This is possible (I did it) but it is messy, and I didn't manage to keep all project specifics out - I still have some hardcoded stuff in my templates. Expect some of mucking around with Reveng Strategy classes, and a lot of hair-pulling and TMI moments reading Hibernate3 sources. Heck, Hibernate Tools don't even document which data are available to the templates, the stereotype answer to questions has been "sorry, the docs aren't ready yet, please read the sources" (and Hibernate Tools development seems to have come to a standstill).


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 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.