-->
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.  [ 7 posts ] 
Author Message
 Post subject: hbm2hbmxml - how do I change default-access attribute?
PostPosted: Wed Dec 03, 2008 6:00 pm 
Newbie

Joined: Tue Nov 11, 2008 12:36 am
Posts: 14
I'm generating mapping files with hbm2hbmxml. I'd like to generate hibernate mappings with default-access="field". Is there a way to do this similar to using a custom reverse strategy? I can see from the source that the template system uses a HibernateMappingGlobalSettings class to get these settings. Is there a way to provide one of these to hbm2hbmxml?

Thanks for your help.

_________________
This signature left intentionally blank.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2008 6:41 pm 
Newbie

Joined: Tue Nov 11, 2008 12:36 am
Posts: 14
I read more of the hibernate tools docs. Could I use a custom exporter rather than hbm2hbmxml? I

Code:
<hbmtemplate
exporterclass="tribal.tool.TribalMappingExporter"
filepattern="."/>
</hibernatetool>


'm thinking I would subclass HibernateMappingExporter, then set the correct setting in the HibernateMappingGlobalSettings that it contains. So,

Code:
globalSettings.setDefaultAccess("field");


Sound right?

_________________
This signature left intentionally blank.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 03, 2008 7:12 pm 
Newbie

Joined: Tue Nov 11, 2008 12:36 am
Posts: 14
I went ahead and created the custom exporter as previously described. Here it is:

Code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package tribal.tool;

import org.hibernate.tool.hbm2x.HibernateMappingExporter;

/**
*
* @author Ezward
*/
public class TribalMappingExporter extends HibernateMappingExporter
{
   public TribalMappingExporter()
   {
      super();
      globalSettings.setDefaultAccess("field");
   }
}


Here is my build target:

Code:
   <!-- let ant know about the hibernatetool task -->
   <taskdef name="hibernatetool"
             classname="org.hibernate.tool.ant.HibernateToolTask" />

    <!-- pre-compile task to regenrate domain classes and mapping files -->
   <target name="-pre-compile">
   </target>

    <!-- generate the domain classes and mapping files -->
    <target name="generate-domain-from-db"
            description="run the hibernate task to generate domain classes and mapping files" >
        <!-- run the hibernate task to generate domain classes and mapping files -->
        <hibernatetool destdir="src">
            <!-- classpath to hibernate mappings and reveng files -->
            <classpath>
                <path location="src/tribal/domain"/>
            </classpath>

            <!--
            we are using jdbc to read configuration from database.
            we are using a reverse strategy to generate abstract
            domain classes.  The TribalDomainGeneration project
            builds the reverse strategy class.  You must build the
            project and add the resulting jar (in dist) to the ant
            libraries (in the tools/options menu).
         -->
            <jdbcconfiguration
                propertyfile="src/tribal/domain/hibernate.properties"
                revengfile="src/tribal/domain/hibernate.reveng.xml"
                packagename="tribal.domain"
                detectmanytomany="true"
            reversestrategy="tribal.tool.TribalDomainStrategy"
            />
         
         <!-- order of generators is important -->
            <!-- we are generating the hbm.xml files -->
         <hbmtemplate exporterclass="tribal.tool.TribalMappingExporter" filepattern="."/>

            <!-- we are generating the java files -->
            <hbm2java jdk5="true" />

            <!-- we are generating the hibernate config file -->
            <hbm2cfgxml destdir="src/tribal/domain" />
        </hibernatetool>
    </target>


I get the following exception when I try to run the target:

Code:
generate-domain-from-db:
Executing Hibernate Tool with a JDBC Configuration (for reverse engineering)
1. task: generic exporterclass: tribal.tool.TribalMappingExporter
An exception occurred while running exporter #2:generic exporterclass: tribal.tool.TribalMappingExporter
To get the full stack trace run ant with -verbose
org.hibernate.tool.hbm2x.ExporterException: Error while processing Configuration with template hbm/hibernate-mapping.hbm.ftl
freemarker.template.TemplateModelException: No signature of method getTag matches the arguments
org.hibernate.tool.hbm2x.ExporterException: Error while processing Configuration with template hbm/hibernate-mapping.hbm.ftl
        at org.hibernate.tool.hbm2x.TemplateHelper.processTemplate(TemplateHelper.java:261)
        at org.hibernate.tool.hbm2x.TemplateProducer.produceToString(TemplateProducer.java:67)
        at org.hibernate.tool.hbm2x.TemplateProducer.produce(TemplateProducer.java:28)
        at org.hibernate.tool.hbm2x.TemplateProducer.produce(TemplateProducer.java:103)
        at org.hibernate.tool.hbm2x.GenericExporter$1.process(GenericExporter.java:31)
        at org.hibernate.tool.hbm2x.GenericExporter.doStart(GenericExporter.java:128)
        at org.hibernate.tool.hbm2x.HibernateMappingExporter.doStart(HibernateMappingExporter.java:34)
        at org.hibernate.tool.hbm2x.AbstractExporter.start(AbstractExporter.java:95)
        at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:40)
        at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:357)
        at org.apache.tools.ant.Target.performTasks(Target.java:385)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1306)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1189)
        at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:273)
        at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:499)
        at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)
Caused by: freemarker.template.TemplateModelException: No signature of method getTag matches the arguments
        at freemarker.ext.beans.MethodMap.getMemberAndArguments(MethodMap.java:94)
        at freemarker.ext.beans.OverloadedMethodModel.exec(OverloadedMethodModel.java:101)
        at freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:93)
        at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
        at freemarker.core.Expression.getStringValue(Expression.java:93)
        at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
        at freemarker.core.Environment.visit(Environment.java:208)
        at freemarker.core.MixedContent.accept(MixedContent.java:92)
        at freemarker.core.Environment.visit(Environment.java:208)
        at freemarker.core.Environment.include(Environment.java:1481)
        at freemarker.core.Include.accept(Include.java:169)
        at freemarker.core.Environment.visit(Environment.java:208)
        at freemarker.core.MixedContent.accept(MixedContent.java:92)
        at freemarker.core.Environment.visit(Environment.java:208)
        at freemarker.core.Environment.process(Environment.java:188)
        at freemarker.template.Template.process(Template.java:237)
        at org.hibernate.tool.hbm2x.TemplateHelper.processTemplate(TemplateHelper.java:255)
        ... 25 more


Any help would be appreciated. Thanks.

_________________
This signature left intentionally blank.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 04, 2008 8:08 pm 
Newbie

Joined: Tue Nov 11, 2008 12:36 am
Posts: 14
I'm trying a different avenue now. I"m trying to modify the templates to always add the default-access="field" attribute to the <hibernate-mapping> tag when I generate the hbm.xml files.

I have read all the docs and looked at the source code, but I still do not understand the semantics of the <hbmtemplate> attributes.

I'm trying to create an equivalient to:

Code:
         <hbm2hbmxml destdir="src"/>


However, I don't understand the sematics of templateprefix, or template (or filepattern really). I have a customized version of hibernate-mapping.hbm.ftl and I want to use that. Do I need all the templates or can I just use this one? How do I specify it's path within my source? Do I need to duplicate the templates folder in the Hibernate-Tools src folder?

Do I only need to specify the updated template (it is not the base template for the generation).

So, I'm not sure where to go. This is what I have;
Code:
            <hbmtemplate
                templateprefix="hbm/"
                template="hibernate-mapping.hbm.ftl"
                filepattern="{package-name}/{class-name}.hbm.xml">
                   
                <property key="destdir" value="src"/>
               
            </hbmtemplate>


but it creates the following errors when run;

Code:
2. task: generic exportertemplate: tool/hibernate-mapping.hbm.ftl
An exception occurred while running exporter #3:generic exportertemplate: tool/hibernate-mapping.hbm.ftl
To get the full stack trace run ant with -verbose
org.hibernate.tool.hbm2x.ExporterException: Error while processing Entity: tribal.domain.MessageConversations with template tool/hibernate-mapping.hbm.ftl
java.io.FileNotFoundException: Template tool/hibernate-mapping.hbm.ftl not found.
org.hibernate.tool.hbm2x.ExporterException: Error while processing Entity: tribal.domain.MessageConversations with template tool/hibernate-mapping.hbm.ftl
        at org.hibernate.tool.hbm2x.TemplateHelper.processTemplate(TemplateHelper.java:258)
        at org.hibernate.tool.hbm2x.TemplateProducer.produceToString(TemplateProducer.java:67)
        at org.hibernate.tool.hbm2x.TemplateProducer.produce(TemplateProducer.java:28)
        at org.hibernate.tool.hbm2x.TemplateProducer.produce(TemplateProducer.java:103)
        at org.hibernate.tool.hbm2x.GenericExporter.exportPOJO(GenericExporter.java:148)
        at org.hibernate.tool.hbm2x.GenericExporter.exportPersistentClass(GenericExporter.java:137)
        at org.hibernate.tool.hbm2x.GenericExporter$2.process(GenericExporter.java:43)
        at org.hibernate.tool.hbm2x.GenericExporter.doStart(GenericExporter.java:128)
        at org.hibernate.tool.hbm2x.AbstractExporter.start(AbstractExporter.java:95)
        at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:40)
        at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:357)
        at org.apache.tools.ant.Target.performTasks(Target.java:385)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1306)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1189)
        at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:273)
        at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:499)
        at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:151)
Caused by: java.io.FileNotFoundException: Template tool/hibernate-mapping.hbm.ftl not found.
        at freemarker.template.Configuration.getTemplate(Configuration.java:489)
        at freemarker.template.Configuration.getTemplate(Configuration.java:452)
        at org.hibernate.tool.hbm2x.TemplateHelper.processTemplate(TemplateHelper.java:254)
        ... 26 more


Thank you for any help you can give.

_________________
This signature left intentionally blank.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 06, 2008 2:19 am 
Newbie

Joined: Tue Nov 11, 2008 12:36 am
Posts: 14
I have finally figured this out. This solution would have also worked for generating the Abstract domain classes (another post). This turns out to be pretty easy. I used a simple customized template to do this without writing any java code. It is a real shame that the documentation for Hibernate-Tools does not have more explicit information on how to use custom templates. It could really use some _well explained_ examples. It took me a long time to figure this out and it was a very simple piece of information that was needed to figure this out - the semantics of the templatepath attribute of the hibernate-mapping tab. So here is what I found.

Generation of the artifacts in Hibernate-Tools (java, hbm.xml, cfg.xml, etc.) happens through a template system. By customizing the templates, you can change the resulting artifacts that are generated. The current Hibernate-Tools uses the freemarker template system. You can read the freemarker docs, but I found that simply by looking at the templates, I could figure out how to modify them. If you download the Hibernate-Tools source, it will contain the templates. Relative to the root of the project folder, the path to the templates is "./tools/src/templates/".

The structure of the templates folder looks like this

templates/dao - templates for generating daos via <hbm2dao/>
templates/doc - templates for generating documentation
templates/dot - templates for generating ...
templates/hbm - templates for generating mapping files via <hbm2hbmxml/>
templates/lint - not sure
templates/pojo - templates for generating java via <hbm2java/>

The two most important points when using customized templates for artifact generation are;
1. The ant tools task must specify the root of the templates path using the templatepath attribute of the <hibernatetool> tag. So, the path you specify would potentially have the /dao, /doc, /dot, etc. folders within it. For example, my project folder structure looks like this;

project/src - my source
project/src/templates - my templates folder
project/src/templates/hbm - my mapping file templates
project/src/templates/hbm/hibernate-mapping.hbm.ftl - this is the one template file I customized.

So, my ant tools task definition uses a templatespath attribute like this;

Code:
        <hibernatetool destdir="src" templatepath="src/templates/">


Note that the path starts at the project root and leads to the folder containing the template subfolders.

2. Your customized template(s) must have the same name as the original template and must be in the same relative path as the original. You only need to provide the templates that you have customized. In otherwords, don't bother to copy all the templates from the Hibernate-Tools source to your own templates folder and then customize a few. You just need the ones that you will customize. When the Hibernate-Tools tasks (<hbm2java/>, <hbm2hbmxml/>, etc.) run, they will first look in the folder specified by the templatepath attribute for the template and if it is not found, they will get the standard one from the Hibernate-Tools.jar.

In my case, I was generating hibernate mapping files from the database using <hbm2hbmxml/> I simply wanted to make my hibernate mapping files using the default-access="field" attribute in the <hibernate-mapping/> tag, to force hibernate to use direct field access rather than getter/setter access. The first thing I had to do was identify the template that was used to generate the hbm.xml file. I looked for likely suspects in the templates/hbm folder. I found templates/hbm/hibernate-mapping.hbm.ftl. It looks like this:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- Generated ${date} by Hibernate Tools ${version} -->
<#if hmgs?exists && hmgs.hasNonDefaultSettings()>
<hibernate-mapping
<#if hmgs.hasDefaultPackage()>
package="${hmgs.defaultPackage}"
</#if>
<#if hmgs.hasSchemaName()>
schema="${hmgs.schemaName}"
</#if>
<#if hmgs.hasCatalogName()>
catalog="${hmgs.catalogName}"
</#if>
<#if hmgs.hasNonDefaultCascade()>
default-cascade="${hmgs.defaultCascade}"
</#if>
<#if hmgs.hasNonDefaultAccess()>
default-access="${hmgs.defaultAccess}"
</#if>
<#if !hmgs.isDefaultLazy()>
   default-lazy="false"
   </#if>
<#if !hmgs.isAutoImport()>
   auto-import="false"
</#if>>
<#else>
<hibernate-mapping>
</#if>

<#include "persistentclass.hbm.ftl"/>

</hibernate-mapping>


Mine looks like this:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- Generated ${date} by Hibernate Tools ${version} -->
<#if hmgs?exists && hmgs.hasNonDefaultSettings()>
<hibernate-mapping
<#if hmgs.hasDefaultPackage()>
package="${hmgs.defaultPackage}"
</#if>
<#if hmgs.hasSchemaName()>
schema="${hmgs.schemaName}"
</#if>
<#if hmgs.hasCatalogName()>
catalog="${hmgs.catalogName}"
</#if>
<#if hmgs.hasNonDefaultCascade()>
default-cascade="${hmgs.defaultCascade}"
</#if>
<#if hmgs.hasNonDefaultAccess()>
default-access="${hmgs.defaultAccess}"
<#else>
default-access="field"
</#if>
<#if !hmgs.isDefaultLazy()>
   default-lazy="false"
   </#if>
<#if !hmgs.isAutoImport()>
   auto-import="false"
</#if>>
<#else>
<hibernate-mapping default-access="field">
</#if>

<#include "persistentclass.hbm.ftl"/>

</hibernate-mapping>


I added this section:

Code:
<#if hmgs.hasNonDefaultAccess()>
default-access="${hmgs.defaultAccess}"
<#else>
default-access="field"


This is added in the section that inserts various kinds of non-default values. This checks to see if there is already a default-access value set. If so, I honor it. If not, I force default-access to "field".

The other place is this:


Code:
<#else>
<hibernate-mapping default-access="field">


Basically, is just adds the default-access-"field" to the tag when no other non-default values exist.

With this in place and my templatepath correctly set so Hibernate-Tools can find it, may regular old <hbm2hbmxml/> task now generates my own custom mapping files.

For completeness, here is my full hibernatetools task in my ant build.xml file:


Code:
   <!-- let ant know about the hibernatetool task -->
   <taskdef name="hibernatetool"
             classname="org.hibernate.tool.ant.HibernateToolTask" />

    <!-- pre-compile task to regenrate domain classes and mapping files -->
   <target name="-pre-compile">
   </target>

    <!-- generate the domain classes and mapping files -->
    <target name="generate-domain-from-db"
            description="run the hibernate task to generate domain classes and mapping files" >
        <!-- run the hibernate task to generate domain classes and mapping files -->
        <hibernatetool destdir="src" templatepath="src/templates/">
            <!-- classpath to hibernate mappings and reveng files -->
            <classpath>
                <path location="src/tribal/domain"/>
            </classpath>

            <!--
            we are using jdbc to read configuration from database.
            we are using a reverse strategy to generate abstract
            domain classes.  The TribalDomainGeneration project
            builds the reverse strategy class.  You must build the
            project and add the resulting jar (in dist) to the ant
            libraries (in the tools/options menu).
         -->
            <jdbcconfiguration
                propertyfile="src/tribal/domain/hibernate.properties"
                revengfile="src/tribal/domain/hibernate.reveng.xml"
                packagename="tribal.domain"
                detectmanytomany="true"
            />
         
         <!-- order of generators is important -->
            <!-- we are generating the hbm.xml files -->
         <hbm2hbmxml destdir="src"/>

            <!-- we are generating the java files -->
            <hbm2java jdk5="true" />

            <!-- we are generating the hibernate config file -->
            <hbm2cfgxml destdir="src/tribal/domain" />
        </hibernatetool>
    </target>

_________________
This signature left intentionally blank.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 06, 2008 5:20 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
sorry for jumping in late. Looks like you got it all covered ? Otherwise let me know ;)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject: Re: hbm2hbmxml - how do I change default-access attribute?
PostPosted: Tue Aug 18, 2009 11:34 am 
Beginner
Beginner

Joined: Fri Jan 23, 2009 10:34 am
Posts: 25
Location: Switzerland
I wanted to do the same for hbm2java and ended with HBX-1132.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.