HiberObjects

Download

Order

Forum

Vote for this plugin

It is currently Fri Sep 03, 2010 6:01 pm

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: hbm generated with many to many rather than one to many
PostPosted: Fri Jan 22, 2010 9:31 am 
Offline

Joined: Fri Jan 15, 2010 9:43 am
Posts: 46
URGENT: Compared to the other issues I have raised I would appreciate it if this issue could be resolved first so I can avoid hand editing the hbm.xml files each time they are code generated.

I have specified in a class diagram similar to the example at:

http://objectgeneration.com/eclipse/index.html

a one-to-many relationship like there is between Customer and Ticket but in the generated hbm.xml file it has many-to-many. I presume that should be one-to-many by using the unique=true modifier. I tried working around this by adding a unique=true tag to the relationship in the diagram but the code is not generated correctly because it is placed as part of the set rather than many-to-many. Code generated is:

<set name='scanPage' table='tb_scan_scan_page' unique='true'>
<key column='scanid' foreign-key='fk_scan_scan_page_key'/>
<many-to-many class='com.pinkwater.trader.server.ScanPage' foreign-key='fk_scan_scan_page' column='scan_page_id' />
</set>

but I think it should be:

<set name='scanPage' table='tb_scan_scan_page'>
<key column='scanid' foreign-key='fk_scan_scan_page_key'/>
<many-to-many class='com.pinkwater.trader.server.ScanPage' foreign-key='fk_scan_scan_page' column='scan_page_id' unique='true' />
</set>

I am using the following as a reference (hopefully it is correct!):

http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-one-to-many-1.html

Thanks.


Last edited by skurlow on Mon Jan 25, 2010 9:44 am, edited 1 time in total

Report this post
 
 Profile  
Reply with quote  
 Post subject: Re: hbm generated with many to many rather than one to many
PostPosted: Mon Jan 25, 2010 9:39 am 
Offline

Joined: Fri Jan 15, 2010 9:43 am
Posts: 46
After more investigation by running the HibernateHelper I don't need the 'many-to-many' table created so I don't think this is correct:

<set name='scanPage' table='tb_scan_scan_page'>
<key column='scanid' foreign-key='fk_scan_scan_page_key'/>
<many-to-many class='com.pinkwater.trader.server.ScanPage' foreign-key='fk_scan_scan_page' column='scan_page_id' unique='true' />
</set>

and it seems the following would be more correct for a one-to-many relationship:

<set name='scanPage' >
<key column='scanid' foreign-key='fk_scan_scan_page_key'/>
<one-to-many class='com.pinkwater.trader.server.ScanPage' />
</set>


Report this post
 
 Profile  
Reply with quote  
 Post subject: Re: hbm generated with many to many rather than one to many
PostPosted: Mon Jan 25, 2010 12:45 pm 
Offline

Joined: Tue Apr 10, 2007 4:42 pm
Posts: 561
Location: Uppsala, Sweden
Hi skurlow,

I'll look into it now.

The generation of the hbm.xml files can be controlled with the hbm.template, but I realize that this is complicated, and the default template should of course work correctly.

May I ask why you are using hbm.xml files instead of JPA annotations? I have been thinking about removing support for hbm.xml files and only support JPA annotations, but I won't do that if people still use hbm.xml files.

Regards,
Lars


Report this post
 
 Profile  
Reply with quote  
 Post subject: Re: hbm generated with many to many rather than one to many
PostPosted: Mon Jan 25, 2010 12:53 pm 
Offline

Joined: Tue Apr 10, 2007 4:42 pm
Posts: 561
Location: Uppsala, Sweden
I cannot reproduce this. When I create a class diagram with a 1 - * association between Customer and Ticket, I get the following in Customer.hbm.xml:
Code:
      <set  name='tickets' inverse='true'>
         <key column='customer_id' foreign-key='fk_ticket_customer_key'/>
         <one-to-many class='com.xyz.myproject.model.Ticket' />
      </set>
and the following in Ticket.hbm.xml:
Code:
      <many-to-one  name='customer' class='com.xyz.myproject.model.Customer' not-null='true' cascade='save-update' foreign-key='fk_ticket_customer_id'>
         <column name='customer_id'/>
      </many-to-one>


Report this post
 
 Profile  
Reply with quote  
 Post subject: Re: hbm generated with many to many rather than one to many
PostPosted: Tue Jan 26, 2010 6:24 am 
Offline

Joined: Fri Jan 15, 2010 9:43 am
Posts: 46
Hi Lars,

What I had done is created an aggregation that was 1 to many and the hbm.xml file was created as I originally wrote. I tried changing it to be an association by unticking the menu option for aggregation but the hbm.xml file is still generated the same way. It seems as though changing the relationship from an aggregation to association is only updating the diagram display but not the code generation.

Does that help to reproduce the problem?

Thanks,
Stephen


Report this post
 
 Profile  
Reply with quote  
 Post subject: Re: hbm generated with many to many rather than one to many
PostPosted: Tue Jan 26, 2010 6:27 am 
Offline

Joined: Fri Jan 15, 2010 9:43 am
Posts: 46
lars wrote:
Hi skurlow,

May I ask why you are using hbm.xml files instead of JPA annotations? I have been thinking about removing support for hbm.xml files and only support JPA annotations, but I won't do that if people still use hbm.xml files.

Regards,
Lars


Hi Lars,

I'm not familiar with using JPA but I have used Hibernate hence why I use hbm.xml files. Can I use JPA together with Hibernate and not use hbm.xml files? I'll search google to see if I can find an answer too.

Thanks,
Stephen


Report this post
 
 Profile  
Reply with quote  
 Post subject: Re: hbm generated with many to many rather than one to many
PostPosted: Tue Jan 26, 2010 7:00 am 
Offline

Joined: Fri Jan 15, 2010 9:43 am
Posts: 46
lars wrote:
I cannot reproduce this. When I create a class diagram with a 1 - * association between Customer and Ticket, I get the following in Customer.hbm.xml:
Code:
      <set  name='tickets' inverse='true'>
         <key column='customer_id' foreign-key='fk_ticket_customer_key'/>
         <one-to-many class='com.xyz.myproject.model.Ticket' />
      </set>
and the following in Ticket.hbm.xml:
Code:
      <many-to-one  name='customer' class='com.xyz.myproject.model.Customer' not-null='true' cascade='save-update' foreign-key='fk_ticket_customer_id'>
         <column name='customer_id'/>
      </many-to-one>



Hi Lars,

I think I figured out what we are doing differently. I think you had defined the association as bi-directional but I had it defined as uni-directional. So the problem seems to only occur for uni-directional associations. Can this please be fixed?

Thanks,
Stephen


Report this post
 
 Profile  
Reply with quote  
 Post subject: Re: hbm generated with many to many rather than one to many
PostPosted: Thu Jan 28, 2010 5:52 pm 
Offline

Joined: Tue Apr 10, 2007 4:42 pm
Posts: 561
Location: Uppsala, Sweden
I have fixed this. Please create a file in your project root called hbm.template with the following content:
Code:
<%
import org.apache.log4j.Logger
import com.objectgen.core.*
import com.objectgen.types.*
import com.objectgen.codegen.hibernate.*


// Configure MySQL specifics by setting database='mysql'
def database = ''


log = Logger.getLogger("com.objectgen.codegen.hibernate.hbm-template")

collectionTypes = [ 'set', 'list', 'bag', 'idbag', 'map' ]

// Handle subclasses with Table per class hierarchy.
// Find all Persistent subclasses in the same package.
subclasses = []
for(sub in c.packageData.classifiers) {
   if(sub.stereotype?.name == 'Persistent' && sub.superClass == c) {
      subclasses.add(sub)
   }
}

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

<!-- Generated by HiberObjects. DO NOT EDIT! --><% /* Feel free to edit this template, but not the generated xml file. */ %>
<hibernate-mapping>
   <class name='${className(c)}' table='${tagParamValue(c, '@hibernate', 'table', tableName(c.name))}'>
<%
// Generate <version> if a tag @hibernate.version is designed.
version = TagUtils.findTag(c, '@hibernate.version')
if(version != null) {
%>      <version${tagParameters(version)}/>
<%
}

// First, generate id or composite-id.
for(var in c.variables) {
   String propertyName = propertyName(var)
   if(var.stereotype?.name == 'id') {
      if(var.attributeType) {
         generatorClass = tagParamValue(var, '@hibernate', 'generator.class', 'native')
%>      <id name='${propertyName}' type='${javaType2Hibernate(var.type)}' column='${idColumn(c, var)}'>
         <generator class='${generatorClass}' />
      </id>
<%     } else {
%>      <composite-id name='${propertyName}' class='${var.type.fullName}'><%
       for(compositeVar in var.type.variables) {
         if(!compositeVar.isStatic() && !compositeVar.isFinal()) { %>
        <key-property name='${propertyName(compositeVar)}'/><%
         }
       } %>
      </composite-id>
<%
       }
   }
}

if(!subclasses.empty) {
%>      <discriminator column='${c.name.toLowerCase()}_type' type='string'/>
<%
}

// Iterate through all variables in the class 2 times,
// first for the elements in <natural_id>, then for the rest.
for(boolean natural_id in [true,false])
{
  for(var in c.variables) {
    if(natural_id != (var.stereotype?.name == 'natural id'))
      continue
   
    if(var.isStatic() || var.isFinal())
      continue

   // Skip <<id>>, it is already generated.
   if(var.stereotype?.name == 'id')
      continue
   
    // Don't generate relations to non-persistent classes.
    if(!variableIsPersistent(var))
      continue

   String propertyName = propertyName(var)
   element = null
   inverse = var.inverse
   inverseMultiplicity = (inverse != null ? inverse.multiplicity : var.inverseMultiplicity)
   inverseSingle = (inverseMultiplicity == '1' || inverseMultiplicity == '0..1')
   hibernateTag = null
   collectionRefType = null
   childElements = []
   childIndex = [:]
   attributes = [:]
   columns = []
   naturalId = findNaturalId(var.type)
    Variable varId = findId(var.type)
   Variable compositeId = null
    if(varId != null && !varId.type.attributeType) {
       compositeId = varId
    }

   attributes['name'] = propertyName
   if(var.attributeType) {
      // The variable is an attribute.
      element = 'property'
      if(database == 'mysql' && (var.type.name == 'boolean' || var.type.name == 'Boolean') ) {
         attributes['type'] = javaType2Hibernate(var.type)
         childIndex.put('column', childElements.size())
         sqlTypeParam = new TagParameter('column.sql-type', 'boolean')
         childElements.add( [ sqlTypeParam ] )
      } else {
         attributes['type'] = javaType2Hibernate(var.type)
         attributes['column'] = mixedCase2UnderScore(var.name)
      }
      hibernateTag = TagUtils.findTag(var, '@hibernate.property')
      if(hibernateTag == null)
         hibernateTag = TagUtils.findTag(var, '@hibernate')
      debug 'attribute: ' + var
   } else if(!mapAsSet(var)) {
      // The variable is a single association.
      attributes['class'] = className(var.type)
      singleTypes = [ 'many-to-one', 'one-to-one', 'component' ]
      for(s in singleTypes ) {
         hibernateTag = TagUtils.findTag(var, '@hibernate.' + s)
         if(hibernateTag != null) {
            element = s
            break
         }
      }
      if(hibernateTag == null) {
         hibernateTag = TagUtils.findTag(var, '@hibernate')
      }
      if(element == null) {
         // Map 1 to 1 associations to a many-to-one and a one-to-one relation.
         if(inverseSingle && (c.name >= var.type.name))
            element = 'one-to-one'
         else
            element = 'many-to-one'
      }
      if(element == 'one-to-one' && inverse != null)
         attributes['property-ref'] = inverse.name
      if(element != 'one-to-one' && element != 'component' && var.multiplicity == var.ONE) {
         attributes['not-null'] = 'true'
         attributes['cascade'] = 'save-update'
      }
      if(element == 'many-to-one') {
         String col = (naturalId != null ? naturalId.name : 'id')
         attributes['foreign-key'] = 'fk_' + mixedCase2UnderScore(baseClassName(c.name) + '_' + var.name) + '_' + col
         if(findColumnNameTag(var) != null) {
            // The <column> elements are generated by tags. Do nothing here.
         } else if(compositeId != null) {
             for(compositeVar in compositeId.type.variables) {
                columns.add( mixedCase2UnderScore(propertyName(compositeVar)) )
             }
         } else {
            columns.add( mixedCase2UnderScore(propertyName) + '_' + col )
         }
         
         if(inverseSingle) {
            attributes['unique'] = 'true'
         }
         if(naturalId != null) {
            attributes['property-ref'] = naturalId.name
         }
      }
/* TODO Generate cascade=all in the inverse end of 1 multiplicity?
      if(element == 'many-to-one' || element == 'one-to-one')
         attributes['cascade'] = 'all'
*/
      debug 'single association: hibernateTag=' + hibernateTag + ', element=' + element
   } else {
      // The variable is a multiple association.
      // Generate a <set>
      // The user can generate <list>, <bag> etc by designing a tag like "@hibernate.list".
      element = 'set'
      String generateCollectionsAsSet = c.codeGenerator.getOption(PersistentFactory.GENERATE_COLLECTIONS_AS_SET)
      debug 'generateCollectionsAsSet=' + generateCollectionsAsSet
      if(generateCollectionsAsSet != null && generateCollectionsAsSet == 'false') {
         element = 'list'
      }
      for(s in collectionTypes ) {
         hibernateTag = TagUtils.findTag(var, '@hibernate.' + s)
         if(hibernateTag != null) {
            element = s
            break
         }
      }
      if(hibernateTag == null) {
         hibernateTag = TagUtils.findTag(var, '@hibernate')
      }
      debug 'multiple association: hibernateTag=' + hibernateTag + ', element=' + element

      // See if this is a bidirectional association.
      debug "inverse=${inverse}, inverseMultiplicity=${inverseMultiplicity}, inverseSingle=${inverseSingle}"
      if(inverseSingle) {
         collectionRefType = 'one-to-many'
         if(inverse != null) {
            attributes['inverse'] = 'true'
         }
         debug "${var} aggregate=${var.aggregate}, ${inverse}"
         if(var.aggregate) {
            if(inverseMultiplicity == '1') {
               attributes['cascade'] = 'all,delete-orphan'
            } else {
               attributes['cascade'] = 'all'
            }
         }
      }
      else {
         collectionRefType = 'many-to-many'
         if(inverse != null) {
            attributes['inverse'] = (c.name >= var.type.name)
         }
         relation = null
         if(var.associationName != null) {
            relation = var.associationName
         } else if(inverse != null && c.name >= var.type.name) {
            relation = baseClassName(var.type.name) + '_' + baseClassName(c.name)
         } else {
            relation = baseClassName(c.name) + '_' + baseClassName(var.type.name)
         }
         attributes['table'] = tableName(relation)
      }
   }
   
   // Collect parameters to the @hibernate tag.
   // These may override the default attributes set earlier.
   if(hibernateTag != null) {
      debug 'hibernateTag=' + hibernateTag
      for(param in hibernateTag.parameters) {
          if(param.name.startsWith('column.')) {
             attributes.remove('column')
          }
         ix = param.name.indexOf(".")
         if(ix < 0) {
            attributes[param.name] = param.value
         }
         else {
            // Join duplicate elements in the list.
            elementName = param.name.substring(0, ix)
            if(childIndex.containsKey(elementName)) {
               index = childIndex.get(elementName)
               childElements.get(index).add(param)
               debug 'add to <' + elementName + '>: childElements=' + childElements
            } else {
               childIndex.put(elementName, childElements.size())
               childElements.add( [ param ] )
               debug 'new element <' + elementName + '>: childElements='+ childElements
            }
         }
      }
   }

   // Generate mapping for the variable.
   // Generate <natural-id> around 1 property if it has that stereotype.
   // TODO Support multiple elements in the same <natural-id>
   if(natural_id) {
%>      <natural-id>
<% }
%>      <${element} <%
   for(key in attributes.keySet()) {
%> ${key}='${attributes[key]}'<%
   }
%>>
<% for(paramList in childElements) {
      param1 = paramList.get(0)
      ix = param1.name.indexOf(".")
      elementName = param1.name.substring(0, ix)
      if(elementName != collectionRefType) {
         debug 'generate <' + elementName + '> parameters: ' + paramList
%>         <${elementName}<%
         for(param in paramList) {
            attrName = param.name.substring(ix+1)
%> ${attrName}='${param.value}'<%
         }
%>/>
<%
      }
   }
   
   for(column in columns) {
%>         <column name='${column}'/>
<%
   }

   // For map, set, list and bag, generate <key column='...'>
   if(['map', 'set', 'list', 'bag'].contains(element) && !childIndex.containsKey('key')) {
      def fk = 'fk_' + mixedCase2UnderScore(baseClassName(c.name) + '_' + baseClassName(var.type.name)) + '_key'
      def idCol = idColumn(c, null)
      if(inverse != null) {
         def inverseNaturalId = findNaturalId(c)
         String col = (inverseNaturalId != null ? inverseNaturalId.name : 'id')
         idCol = mixedCase2UnderScore(inverse.name) + '_' + col
         fk = 'fk_' + mixedCase2UnderScore(baseClassName(var.type.name) + '_' + inverse.name) + '_key'
      }
%>         <key column='${idCol}' foreign-key='${fk}'/>
<% }

   // For map and list, generate <index>
   if((element == 'map' || element == 'list') && !childIndex.containsKey('index')) {
%>         <index column='${indexColumn(var)}'<%
      if(element == 'map') {
%> type='string'<%
      }
%> />
<% }

   // For multiple associations, generate <many-to-many> unless <one-to-many>,
   // <element>, <many-to-one> or <composite-element> has already been generated.
   foundChild = findMapValue(childIndex, ['one-to-many', 'element', 'composite-element', 'many-to-one', 'many-to-any'])
   if(!var.attributeType && mapAsSet(var) && foundChild == null) {
      debug 'Generate collectionRefType=' + collectionRefType
%>         <${collectionRefType} class='${className(var.type)}'<%
      if(collectionRefType == 'many-to-many') {
     
         def fk = 'fk_' + mixedCase2UnderScore(baseClassName(c.name) + '_' + propertyName)
         %> foreign-key='${fk}'<%
         
         String column = null
         if(naturalId != null) {
            column = naturalId.name
         } else if(compositeId == null) {
             column = relationColumn(c,var,inverse)
          }

         if(column != null) {
            %> column='${column}'<%
         }
         
         if(naturalId != null) {
            %> property-ref='${naturalId.name}'<%
         }
      }
     
      // Generate the @hibernate tag parameters.
      for(paramList in childElements) {
         param1 = paramList.get(0)
         ix = param1.name.indexOf(".")
         elementName = param1.name.substring(0, ix)
         if(elementName == collectionRefType) {
            debug 'generate ' + elementName + ' parameters: ' + paramList
            for(param in paramList) {
               attrName = param.name.substring(ix+1)
%> ${attrName}='${param.value}'<%
         }
      }
   }
    if(compositeId != null && collectionRefType != 'one-to-many') {
%> ><%
       for(compositeVar in compositeId.type.variables) { %>
          <column name='${propertyName(compositeVar)}'/><%
       }
%>
         </${collectionRefType}>
<%
    } else {
%> />
<%
    }
}
%>      </${element}>
<%
   if(natural_id) {
%>      </natural-id>
<% }
  }  // end for(var)
}  // end for(natural_id)

// Handle subclasses with Table per class hierarchy.
// The subclasses will not get their own mapping files.
for(sub in subclasses) {
%>      <subclass name="${sub.fullName}" discriminator-value="${sub.name}">
<%
   for(var in sub.variables) {
      if(var.stereotype?.name == 'id')
         continue
      else if(var.isStatic() || var.isFinal())
         continue
       else if(!variableIsPersistent(var))
          continue
      else if(var.attributeType) {
%>         <property name='${propertyName(var)}' type='${javaType2Hibernate(var.type)}' column='${mixedCase2UnderScore(var.name)}'>
         </property>
<%
      }
   }
%>      </subclass>
<%
}

%>   </class>
</hibernate-mapping><%

void debug(s) {
   if(log != null) log.debug(s)
}

boolean variableIsPersistent(var) {
if(var.type instanceof Classifier) {
   Classifier varType = (Classifier) var.type
   if(!varType.attributeType &&
          (varType.stereotype == null ||
           varType.stereotype.name != 'Persistent') )
      return false
    }
    return true
}

Object findMapValue(map, keyList) {
   for(key in keyList) {
      value = map.get(key)
      if(value != null)
         return value
   }
   return null;
}

String tagParamValue(taggedValue, tagName, paramName, defaultValue) {
   param = TagUtils.findTagParameter(taggedValue, tagName, paramName)
   return (param != null ? param.value : defaultValue)
}

String tagParamValue(tag, paramName, defaultValue) {
   param = TagUtils.findTagParameter(tag, paramName)
   return (param != null ? param.value : defaultValue)
}

String tagParameters(tag) {
   buf = new StringBuffer()
   for(param in tag.parameters) {
      buf.append(" ").append(param.name).append("=").append("\'").append(param.value).append("\'")
   }
   return buf
}

/** For a class name "VolumePriceType", return "volum_price_type_id" etc. */
String idColumn(c, id) {
   if(id == null) {
      id = findId(c)
   }
   if(id != null) {
      idColumn = findColumnNameTag(id)
      if(idColumn != null) {
         return idColumn
      }
   }
   s = baseClassName(c.name)
   return mixedCase2UnderScore(s) + '_id'
}

String columnName(var) {
   column = findColumnNameTag(var)
   if(column != null) {
      return column
   } else {
      return mixedCase2UnderScore(var.name)
   }
}

String findColumnNameTag(var) {
    column = tagParamValue(var, '@hibernate', 'column', null)
    if(column == null)
       column = tagParamValue(var, '@hibernate', 'column.name', null)
    return column
}

String className(c) {
   return c.fullName
}

String baseClassName(String s) {
// Can put special handling, for example remove prefix "H"
// if(s[0] == 'H')
//    s = s[1..-1]
   return s
}

// Convert "MyTable" to "tb_my_table"
String tableName(s) {
   s = baseClassName(s)
   buf = new StringBuffer('tb')
   mixedCase2UnderScore(s, buf)
   return buf
}

String indexColumn(var) {
   return mixedCase2UnderScore(var.name) + '_ix'
}

String relationColumn(c, var, inverse) {
   return mixedCase2UnderScore(var.name) + '_id'
}

String inverseRelationColumn(c, var, inverse) {
   if(inverse != null)
      return mixedCase2UnderScore(inverse.name) + '_id'
   else
      return relationColumn(c, var, inverse)
}

String javaType2Hibernate(type) {
   return HibernateTypes.instance.javaType2hibernateType(type.name)
}

/** Convert from "MixedCase" to "mixed_case" etc. */
String mixedCase2UnderScore(String s, StringBuffer buf) {
   for(char ch in s) {
      if(buf.size() > 0 && Character.isUpperCase(ch)) {
         if(buf[-1] != '_')
            buf.append('_')
      }
      buf.append(Character.toLowerCase(ch))
   }
   return buf
}

String mixedCase2UnderScore(String s) {
   return mixedCase2UnderScore(s, new StringBuffer())
}

// Find any variable with stereotype <<natural id>> in a class.
Variable findNaturalId(type) {
   return findVariableStereotype(type, 'natural id')
}

// Find any variable with stereotype <<id>> in a class.
Variable findId(type) {
   return findVariableStereotype(type, 'id')
}

Variable findVariableStereotype(cl, stereotype) {
   if(cl instanceof Classifier && !cl.attributeType) {
      for(var in cl.variables) {
         if(var.stereotype != null && var.stereotype.name == stereotype) {
            return var
         }
      }
   }
   return null
}

// Determine if a relation shall be mapped to a <set>
boolean mapAsSet(var) {
   if(!var.single)
      return true

   for(s in collectionTypes ) {
      hibernateTag = TagUtils.findTag(var, '@hibernate.' + s)
      if(hibernateTag != null)
         return true
   }
   
   return false
}

// Convert variable name to a correct property name
String propertyName(var) {
   String varName = var.name
   if(varName.length() >= 2) {
      if(Character.isUpperCase( (char)varName[1] ) )
         return varName[0].toUpperCase() + varName[1..-1]
      else
         return varName[0].toLowerCase() + varName[1..-1]
   }
   return varName
}
%>

Then set the inverse multiplicity of the association to 1 to test it.

This hbm.template will be part of the next release, and then you can remove it from your project again.

About JPA: Yes, Hibernate supports JPA. Then you can get rid of those XML files. And to try it in HiberObjects, just open Project Properties go to HiberObjects > Persistence and select Platform "Java Persistence API". Then all the code will be regenerated to work with annotations instead of XML files.

Regards,
Lars


Report this post
 
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC + 1 hour [ DST ]


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

Search for:
Jump to:  
cron
Powered by phpBB © 2002, 2006 phpBB Group