[jboss-user] [Persistence, JBoss/CMP, Hibernate, Database] - hbm.xml to javax.persistence annotations problems

mpurdy1973 do-not-reply at jboss.com
Thu Jul 16 11:18:45 EDT 2009


i created a simple hibernate example using two classes:
- User
- TrainingRequest

User has a set of trainingRequest (one to many)
TrainingRequest has a user (many to one)

everything works fine; so i created a new project and converted the *.hbm.xml to annotations, however, it doesnt create the TrainingRequest table correctly and throws exception when trying to build the table.

the details are below, however, i believe the problem seems to be the following:
the TrainingRequest hibernate with the annotations only creates two columns the trainingrequest_id key and the user_id foreign key.

note: i changed the table names from the first project to the second project to simplify the example - but other than that everything is the same.


the join table annotation from the two classes


  | //from User.java
  |    @OneToMany(cascade = CascadeType.ALL)
  |    @JoinTable
  |    (
  |       name="TrainingRequest",
  |       joinColumns = @JoinColumn( name="user_id"),
  |       inverseJoinColumns = @JoinColumn( name="trainingrequest_id")
  |    )
  |    private Set<TrainingRequest> trainingRequests;
  | 
  | 
  | //from TrainingRequest.java
  |    @ManyToOne()
  |    @JoinTable
  |    (
  |       name="User",
  |       joinColumns = @JoinColumn( name="trainingrequest_id"),
  |       inverseJoinColumns = @JoinColumn( name="user_id")
  |    )
  |    private User user;
  | 



User.hbm.xml (from the first project that works)

  | <?xml version="1.0"?> 
  | <!DOCTYPE hibernate-mapping PUBLIC 
  |    "-//Hibernate/Hibernate Mapping DTD//EN"
  |    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  |     
  | <hibernate-mapping> 
  |    <class name="com.pyxisengineering.test.hibernate.model.User" table="users"> 
  |       <id name="id" column="user_id"> 
  |          <generator class="increment" /> 
  |       </id>
  |       <property name="username" column="username" />
  |       <property name="password" column="password" />
  |       
  |       <set name="trainingRequests" inverse="true" cascade="all">
  |          <key column="user_id" />
  |          <one-to-many class="com.pyxisengineering.test.hibernate.model.TrainingRequest" />
  |       </set>  
  |       
  |    </class>
  | 
  | </hibernate-mapping>
  | 

TrainingRequest.hbm.xml (from the first project that works)

  | <?xml version="1.0"?> 
  | <!DOCTYPE hibernate-mapping PUBLIC 
  |    "-//Hibernate/Hibernate Mapping DTD//EN"
  |    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  |     
  | <hibernate-mapping> 
  |    <class name="com.pyxisengineering.test.hibernate.model.TrainingRequest" table="trainingrequests"> 
  |       <id name="id" column="trainingrequest_id"> 
  |          <generator class="increment" /> 
  |       </id>
  |       <property name="subject" column="subject" />
  |       <property name="summary" column="summary" />
  |       <property name="cost" column="cost" />
  |       
  |       <many-to-one name="user" class="com.pyxisengineering.test.hibernate.model.User" column="user_id" not-null="true"/>
  |       
  |    </class>
  | 
  | </hibernate-mapping>
  | 

database hibernate creates in the first project that works

  | mysql> desc users;
  | +----------+--------------+------+-----+---------+-------+
  | | Field    | Type         | Null | Key | Default | Extra |
  | +----------+--------------+------+-----+---------+-------+
  | | user_id  | bigint(20)   | NO   | PRI | NULL    |       | 
  | | username | varchar(255) | YES  |     | NULL    |       | 
  | | password | varchar(255) | YES  |     | NULL    |       | 
  | +----------+--------------+------+-----+---------+-------+
  | 3 rows in set (0.00 sec)
  | 
  | mysql> desc trainingrequests;
  | +--------------------+--------------+------+-----+---------+-------+
  | | Field              | Type         | Null | Key | Default | Extra |
  | +--------------------+--------------+------+-----+---------+-------+
  | | trainingrequest_id | bigint(20)   | NO   | PRI | NULL    |       | 
  | | subject            | varchar(255) | YES  |     | NULL    |       | 
  | | summary            | varchar(255) | YES  |     | NULL    |       | 
  | | cost               | double       | YES  |     | NULL    |       | 
  | | user_id            | bigint(20)   | NO   | MUL | NULL    |       | 
  | +--------------------+--------------+------+-----+---------+-------+
  | 5 rows in set (0.01 sec)
  | 


User.java (from second project with annotations)

  | package com.pyxisengineering.test.hibernate.model;
  | 
  | import java.util.HashSet;
  | import java.util.Set;
  | 
  | import javax.persistence.CascadeType;
  | import javax.persistence.Column;
  | import javax.persistence.Entity;
  | import javax.persistence.GeneratedValue;
  | import javax.persistence.Id;
  | import javax.persistence.JoinTable;
  | import javax.persistence.JoinColumn;
  | import javax.persistence.OneToMany;
  | import javax.persistence.Table;
  | 
  | 
  | 
  | @Entity
  | @Table(name = "User")
  | public class User
  | {
  |    @Id @GeneratedValue
  |    @Column(name = "user_id")
  |    private Long id;
  |    
  |    @Column(name = "username")
  |    private String username;
  |    
  |    @Column(name = "password")
  |    private String password;
  |    
  |    @OneToMany(cascade = CascadeType.ALL)
  |    @JoinTable
  |    (
  |       name="TrainingRequest",
  |       joinColumns = @JoinColumn( name="user_id"),
  |       inverseJoinColumns = @JoinColumn( name="trainingrequest_id")
  |    )
  |    private Set<TrainingRequest> trainingRequests;
  |    
  |    public User()
  |    {
  |       this.init();
  |       
  |    }//end default constructor
  |    
  |    private void init()
  |    {
  |       this.trainingRequests = new HashSet<TrainingRequest>();
  |       
  |    }//end initialization function
  |    
  |    public Long getId()                        { return this.id; }
  |    public void setId(Long id)                 { this.id = id;   }
  |    
  |    public String getUsername()                { return this.username;     }
  |    public void setUsername(String username)   { this.username = username; }
  |    
  |    public String getPassword()                { return this.password;     }
  |    public void setPassword(String password)   { this.password = password; }
  |    
  |    public Set<TrainingRequest> getTrainingRequests()
  |    { 
  |       return this.trainingRequests; 
  |       
  |    }//end method getTrainingRequest
  |    
  |    public void setTrainingRequests(Set<TrainingRequest> trainingRequests)
  |    {
  |       if(trainingRequests != null)
  |          this.trainingRequests = trainingRequests;
  |       else
  |          this.init();
  |       
  |    }//end method setTrainingRequest
  |    
  |    public boolean deleteTrainingRequest(int pos)
  |    {
  |       boolean ret = false;
  |       
  |       if(pos >= 0 && pos < this.trainingRequests.size())
  |       {
  |          this.trainingRequests.remove(pos);
  |          ret = true;
  |          
  |       }//end if in range - delete
  |       
  |       return ret;
  |       
  |    }//end method deleteTrainingRequest
  |    
  |    public void addTrainingRequest(TrainingRequest trainingRequest)
  |    {
  |       trainingRequest.setUser(this);
  |       this.trainingRequests.add(trainingRequest); 
  |            
  |    }//end method addTrainingRequest
  |    
  |    public String toString()
  |    {
  |       StringBuffer ret = new StringBuffer(100);
  |       
  |       ret.append(this.id);
  |       ret.append(", ");
  |       ret.append(this.username);
  |       ret.append(", ");
  |       ret.append(this.password);
  |       
  |       for(TrainingRequest trainingRequest: this.trainingRequests)
  |          ret.append("\n" + trainingRequest.toString());
  |            
  |       ret.append(" )");     
  |       
  |       return ret.toString();
  |       
  |    }//end method toString
  |    
  | }//end class User
  | 

TrainingRequest (from second project with annotations)

  | package com.pyxisengineering.test.hibernate.model;
  | 
  | import javax.persistence.Column;
  | import javax.persistence.Entity;
  | import javax.persistence.GeneratedValue;
  | import javax.persistence.Id;
  | import javax.persistence.JoinColumn;
  | import javax.persistence.JoinTable;
  | import javax.persistence.ManyToOne;
  | import javax.persistence.Table;
  | 
  | @Entity
  | @Table(name = "TrainingRequest")
  | public class TrainingRequest
  | {
  |    @Id @GeneratedValue
  |    @Column(name = "trainingrequest_id")
  |    private Long id;
  |    
  |    @Column(name = "subject")
  |    private String subject;
  |    
  |    @Column(name = "summary")
  |    private String summary;
  |    
  |    @Column(name = "cost")
  |    private Double cost;
  |    
  |    @ManyToOne()
  |    @JoinTable
  |    (
  |       name="User",
  |       joinColumns = @JoinColumn( name="trainingrequest_id"),
  |       inverseJoinColumns = @JoinColumn( name="user_id")
  |    )
  |    private User user;
  |    
  |    public Long getId()                    { return this.id; }
  |    public void setId(Long id)             { this.id = id;   }
  |    
  |    public String getSubject()             { return this.subject;    }
  |    public void setSubject(String subject) { this.subject = subject; }
  |    
  |    public String getSummary()             { return this.summary;    }
  |    public void setSummary(String summary) { this.summary = summary; }
  |    
  |    public Double getCost()                { return this.cost; }
  |    public void setCost(Double cost)       { this.cost = cost; }
  |    
  |    public User getUser()                  { return this.user; }
  |    public void setUser(User user)         { this.user = user; }
  |    
  |    public String toString()
  |    {
  |       StringBuffer ret = new StringBuffer(100);
  |       
  |       ret.append("( ");
  |       
  |       ret.append(this.id);
  |       ret.append(", ");
  |       ret.append(this.subject);
  |       ret.append(", ");
  |       ret.append(this.summary);
  |       ret.append(", ");
  |       ret.append(this.cost);
  |       ret.append(", ");
  |       
  |       if(this.user != null)
  |          ret.append(this.user.getUsername());
  |       else
  |          ret.append("user not set - this should never happen");
  |       
  |       ret.append(" )");
  |       
  |       return ret.toString();
  |       
  |    }//end method toString
  |    
  | }//end class TrainingRequest
  | 


exceptions when running the second project

  | 10:45:09,578  INFO Version:15 - Hibernate Annotations 3.3.1.GA
  | 10:45:09,590  INFO Environment:514 - Hibernate 3.2.7
  | 10:45:09,593  INFO Environment:547 - hibernate.properties not found
  | 10:45:09,595  INFO Environment:681 - Bytecode provider name : cglib
  | 10:45:09,600  INFO Environment:598 - using JDK 1.4 java.sql.Timestamp handling
  | 10:45:09,669  INFO Configuration:1445 - configuring from resource: /hibernate.cfg.xml
  | 10:45:09,669  INFO Configuration:1422 - Configuration resource: /hibernate.cfg.xml
  | 10:45:09,761  INFO Configuration:1560 - Configured SessionFactory: null
  | 10:45:09,820  INFO AnnotationBinder:418 - Binding entity from annotated class: com.pyxisengineering.test.hibernate.model.User
  | 10:45:09,851  INFO EntityBinder:424 - Bind entity com.pyxisengineering.test.hibernate.model.User on table User
  | 10:45:09,928  INFO AnnotationBinder:418 - Binding entity from annotated class: com.pyxisengineering.test.hibernate.model.TrainingRequest
  | 10:45:09,928  INFO EntityBinder:424 - Bind entity com.pyxisengineering.test.hibernate.model.TrainingRequest on table TrainingRequest
  | 10:45:09,933  INFO EntityBinder:635 - Adding secondary table to entity com.pyxisengineering.test.hibernate.model.TrainingRequest -> User
  | Exception in thread "main" org.hibernate.MappingException: Foreign key (FKEA317035A6FF12E4:TrainingRequest [trainingrequest_id])) must have same number of columns as the referenced primary key (TrainingRequest [user_id,trainingrequest_id])
  | 	at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:90)
  | 	at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:73)
  | 	at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1282)
  | 	at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1189)
  | 	at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:324)
  | 	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1305)
  | 	at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
  | 	at com.pyxisengineering.test.hibernate.App.main(App.java:20)
  | 
  | 

View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4244118#4244118

Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4244118



More information about the jboss-user mailing list