-->
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.  [ 2 posts ] 
Author Message
 Post subject: Table generation with annotations and abstract classes
PostPosted: Thu May 10, 2007 11:30 am 
Regular
Regular

Joined: Fri Feb 13, 2004 10:02 pm
Posts: 90
I've included my information below. I'm having a problem with encapsulation of data. As you can see by my code below, I have 4 classes, IdentityVo, AuditableVo, CreditUnion, and ProcessInformation. I would like a 'CreditUnion' table with all the properties of IdentityVo, AuditableVo, and CreditUnion. I also want a 'ProcessInformation' table to contain the properties from IndentityVo, AuditableVo and CreditUnion vo. When using the old mappings, I could generate tables using the hbm2ddl.auto and they would have the correct structure. Hibernate doesn't generate any tables. I've obviously done something incorrectly in my annotations, but I'm not sure how I need to declare this to get my abstract class properties in the same table as my concrete class properties. I thought setting the inheritance strategy would accomplish this. Any help would be greatly appreciated.

Thanks,
Todd

Hibernate version:
3.2.3
Mapping documents:
Identity Class
Code:
package com.purdueefcu.statements.dataaccess.bean;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.hibernate.annotations.AccessType;


/**
* This class is a base class for all data access objects.  It provides functionality for indexing
* and retrieval via a database generated primary key
*
* @author Todd Nine
*/
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class IdentityVo {


   /**
    * The id to map to the identity column of the table
    * No setter is used to avoid programmer error.  Only the database should set the id.
    * @uml.property name="id"
    */
   private Long id = null;

   /**
    * Getter of the property <tt>id</tt>
    *
    * @return Returns the id.
    * @uml.property name="id"
    */
   @Id
   @GeneratedValue (strategy=GenerationType.IDENTITY)
   //override and use direct field access to avoid creating a setter since
   //only hibernate should set the id from the id generated by the db
   @AccessType("field")
   public Long getId() {
      return id;
   }

   /*
    * (non-Javadoc)
    *
    * @see java.lang.Object#hashCode()
    */
   @Override
   public int hashCode() {
      final int PRIME = 31;
      int result = 1;
      result = PRIME * result + ((id == null) ? 0 : id.hashCode());
      return result;
   }

   /*
    * (non-Javadoc)
    *
    * @see java.lang.Object#equals(java.lang.Object)
    */
   @Override
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      final IdentityVo other = (IdentityVo) obj;
      if (id == null) {
         if (other.id != null)
            return false;
      } else if (!id.equals(other.id))
         return false;
      return true;
   }

}


Auditable Class
Code:
package com.purdueefcu.statements.dataaccess.bean;

import java.util.Date;

import javax.persistence.Basic;
import javax.persistence.Entity;
/**
* Base class for auditing
* @author Todd Nine
*
*/
@Entity
public abstract class AuditableVo extends IdentityVo {

   /**
    * The date this object was created
    *
    * @uml.property name="createDate"
    */
   private Date createDate;

   /**
    * The update timestamp
    *
    * @uml.property name="updateDate"
    */
   private Date updateDate;
   
   public AuditableVo() {
      super();
   }

   

   /**
    * Getter of the property <tt>createDate</tt>
    *
    * @return Returns the createDate.
    * @uml.property name="createDate"
    */
   @Basic
   public Date getCreateDate() {
      return createDate;
   }

   /**
    * Setter of the property <tt>createDate</tt>
    *
    * @param createDate
    *            The createDate to set.
    * @uml.property name="createDate"
    */
   public void setCreateDate(Date createDate) {
      this.createDate = createDate;
   }

   /**
    * Getter of the property <tt>updateDate</tt>
    *
    * @return Returns the updateDate.
    * @uml.property name="updateDate"
    */
   @Basic
   public Date getUpdateDate() {
      return updateDate;
   }

   /**
    * Setter of the property <tt>updateDate</tt>
    *
    * @param updateDate
    *            The updateDate to set.
    * @uml.property name="updateDate"
    */
   public void setUpdateDate(Date updateDate) {
      this.updateDate = updateDate;
   }

}


Credit Union Class
Code:
package com.purdueefcu.statements.dataaccess.bean;


import java.util.ArrayList;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;


/**
* The object that contains credit union information
*
* @author Todd Nine
*/
@Entity
@Table(name="CreditUnion")
public class CreditUnion extends AuditableVo {

   /**
    * @uml.property name="name2"
    */
   
   private String name;

   private List<ProcessInformation> processorRuns;

   /**
    *
    */
   public CreditUnion() {
      super();
   }

   /**
    * @return the name
    * @uml.property name="name"
    */
   @Basic
   public String getName() {
      return name;
   }

   /**
    * @param name
    *            the name to set
    * @uml.property name="name"
    */
   public void setName(String name) {
      this.name = name;
   }

   /**
    * @return the processorRuns
    */
   @OneToMany(mappedBy="creditUnion")
   public List<ProcessInformation> getProcessorRuns() {
      return processorRuns;
   }

   /**
    * @param processorRuns
    *            the processorRuns to set
    */
   public void setProcessorRuns(List<ProcessInformation> processorRuns) {
      this.processorRuns = processorRuns;
   }

   /**
    * Add the run to the list of runs
    *
    * @param run
    */
   public void addToProcessorRun(ProcessInformation run) {
      if (this.processorRuns == null) {
         this.processorRuns = new ArrayList<ProcessInformation>();
      }

      this.processorRuns.add(run);
   }

}



ProcessInformation Class
Code:
package com.purdueefcu.statements.dataaccess.bean;

import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Table;


/**
* The object to line a processor run to the Credit Union.
* @author Todd Nine
*
*/
@Entity
@Table(name="ProcessInformation")
public class ProcessInformation extends AuditableVo {

   private CreditUnion creditUnion;
   
   //number of accounts queued in the run
   private Long numberOfAccounts;
   
   /**
    *
    */
   public ProcessInformation() {
      super();
   }

   /**
    * @return the creditUnion
    */
   @ManyToOne
   public CreditUnion getCreditUnion() {
      return creditUnion;
   }

   /**
    * @param creditUnion the creditUnion to set
    */
   public void setCreditUnion(CreditUnion creditUnion) {
      this.creditUnion = creditUnion;
   }

   /**
    * @return the numberOfAccounts
    */
   @Basic
   public Long getNumberOfAccounts() {
      return numberOfAccounts;
   }

   /**
    * @param numberOfAccounts the numberOfAccounts to set
    */
   public void setNumberOfAccounts(Long numberOfAccounts) {
      this.numberOfAccounts = numberOfAccounts;
   }

}


Name and version of the database you are using: MySQL 5, with InnoDB Dialect

Debug level Hibernate log excerpt:

Code:
uilding new Hibernate SessionFactory
Preparing to build session factory with filters : {}
Execute first pass mapping processing
Process hbm files
Process annotated classes
Binding entity from annotated class: com.purdueefcu.statements.dataaccess.bean.IdentityVo
Import with entity name=IdentityVo
Bind entity com.purdueefcu.statements.dataaccess.bean.IdentityVo on table IdentityVo
Processing com.purdueefcu.statements.dataaccess.bean.IdentityVo property annotation
Processing annotations of com.purdueefcu.statements.dataaccess.bean.IdentityVo.id
Binding column id unique false
id is an id
building SimpleValue for id
Building property id
Bind @Id on id
Binding entity from annotated class: com.purdueefcu.statements.dataaccess.bean.AuditableVo
Import with entity name=AuditableVo
Bind entity com.purdueefcu.statements.dataaccess.bean.AuditableVo on table AuditableVo
Processing com.purdueefcu.statements.dataaccess.bean.AuditableVo property annotation
Processing annotations of com.purdueefcu.statements.dataaccess.bean.AuditableVo.createDate
Binding column createDate unique false
binding property createDate with lazy=false
building SimpleValue for createDate
Building property createDate
Processing annotations of com.purdueefcu.statements.dataaccess.bean.AuditableVo.updateDate
Binding column updateDate unique false
binding property updateDate with lazy=false
building SimpleValue for updateDate
Building property updateDate
Binding entity from annotated class: com.purdueefcu.statements.dataaccess.bean.Account
Import with entity name=Account
Bind entity com.purdueefcu.statements.dataaccess.bean.Account on table Account
Processing com.purdueefcu.statements.dataaccess.bean.Account property annotation
Processing annotations of com.purdueefcu.statements.dataaccess.bean.Account.accountNumber
Binding column accountNumber unique false
binding property accountNumber with lazy=false
building SimpleValue for accountNumber
Building property accountNumber
Processing annotations of com.purdueefcu.statements.dataaccess.bean.Account.status
Binding column status unique false
binding property status with lazy=false
building SimpleValue for status
Building property status
Binding entity from annotated class: com.purdueefcu.statements.dataaccess.bean.CreditUnion
Import with entity name=CreditUnion
Bind entity com.purdueefcu.statements.dataaccess.bean.CreditUnion on table CreditUnion
Processing com.purdueefcu.statements.dataaccess.bean.CreditUnion property annotation
Processing annotations of com.purdueefcu.statements.dataaccess.bean.CreditUnion.processorRuns
Binding column null unique false
Binding column processorRuns unique false
Binding column null unique false
Binding column element unique false
Binding column mapkey unique false
Binding column null unique false
Binding column null unique false
Binding column null unique false
Collection role: com.purdueefcu.statements.dataaccess.bean.CreditUnion.processorRuns
Building property processorRuns
Processing annotations of com.purdueefcu.statements.dataaccess.bean.CreditUnion.name
Binding column name unique false
binding property name with lazy=false
building SimpleValue for name
Building property name
Binding entity from annotated class: com.purdueefcu.statements.dataaccess.bean.ProcessInformation
Import with entity name=ProcessInformation
Bind entity com.purdueefcu.statements.dataaccess.bean.ProcessInformation on table ProcessInformation
Processing com.purdueefcu.statements.dataaccess.bean.ProcessInformation property annotation
Processing annotations of com.purdueefcu.statements.dataaccess.bean.ProcessInformation.creditUnion
Binding column null unique false
Binding column creditUnion unique false
Building property creditUnion
Processing annotations of com.purdueefcu.statements.dataaccess.bean.ProcessInformation.numberOfAccounts
Binding column numberOfAccounts unique false
binding property numberOfAccounts with lazy=false
building SimpleValue for numberOfAccounts
Building property numberOfAccounts
processing manytoone fk mappings
processing extends queue
processing collection mappings
Second pass for collection: com.purdueefcu.statements.dataaccess.bean.CreditUnion.processorRuns
Binding a OneToMany: com.purdueefcu.statements.dataaccess.bean.CreditUnion.processorRuns through a foreign key
Mapping collection: com.purdueefcu.statements.dataaccess.bean.CreditUnion.processorRuns -> ProcessInformation
Retrieving property com.purdueefcu.statements.dataaccess.bean.ProcessInformation.creditUnion
Mapped collection key: creditUnion_id, one-to-many: com.purdueefcu.statements.dataaccess.bean.ProcessInformation
processing native query and ResultSetMapping mappings
processing association property references
processing foreign key constraints
resolving reference to class: com.purdueefcu.statements.dataaccess.bean.CreditUnion
ResourceBundle ValidatorMessages not found in Validator classloader. Delegate to org.hibernate.validator.resources.DefaultValidatorMessages
ResourceBundle ValidatorMessages not found in Validator classloader. Delegate to org.hibernate.validator.resources.DefaultValidatorMessages
ResourceBundle ValidatorMessages not found in Validator classloader. Delegate to org.hibernate.validator.resources.DefaultValidatorMessages
ResourceBundle ValidatorMessages not found in Validator classloader. Delegate to org.hibernate.validator.resources.DefaultValidatorMessages
ResourceBundle ValidatorMessages not found in Validator classloader. Delegate to org.hibernate.validator.resources.DefaultValidatorMessages
Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
RDBMS: MySQL, version: 5.0.37-community-nt
JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.0.5 ( $Date: 2007-03-01 00:01:06 +0100 (Thu, 01 Mar 2007) $, $Revision: 6329 $ )
Using dialect: org.hibernate.dialect.MySQLInnoDBDialect
Using default transaction strategy (direct JDBC transactions)
No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
Automatic flush during beforeCompletion(): disabled
Automatic session close at end of transaction: disabled
JDBC batch size: 15
JDBC batch updates for versioned data: disabled
Scrollable result sets: enabled
Wrap result sets: disabled
JDBC3 getGeneratedKeys(): enabled
Connection release mode: on_close
Maximum outer join fetch depth: 2
Default batch fetch size: 1
Generate SQL with comments: disabled
Order SQL updates by primary key: disabled
Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
Using ASTQueryTranslatorFactory
Query language substitutions: {}
JPA-QL strict compliance: disabled
Second-level cache: enabled
Query cache: disabled
Cache provider: org.hibernate.cache.NoCacheProvider
Optimize cache for minimal puts: disabled
Structured second-level cache entries: disabled
Echoing all SQL to stdout
Statistics: disabled
Deleted entity synthetic identifier rollback: disabled
Default entity-mode: pojo
Named query checking : enabled
building session factory
Session factory constructed with filter configurations : {}


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 10, 2007 4:01 pm 
Regular
Regular

Joined: Fri Feb 13, 2004 10:02 pm
Posts: 90
For anyone else who is stumped by this problem learning annotations, the solution is trivial, and I feel like quite the idiot for missing this. After reviewing the examples Hibernate provides for persistence annotations (which is better than Sun's in my opinion), I found the following.

http://www.hibernate.org/hib_docs/annotations/reference/en/html/entity.html#d0e898

Basically, I simply replace '@Entity' with '@MappedSuperclass'. This allows us to inherit the properties, but not create a table for the class. The mapping changes from

Code:
@Entity
//TODO TN, can we do table per subclass?
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)


To this
Code:
@MappedSuperclass
//TODO TN, can we do table per subclass?
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)


Hopefully this will help another annotation noob like me.

Todd


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