在多对多关系中得到org.hibernate.id.IdentifierGenerationException

时间:2013-08-29 15:43:10

标签: java hibernate

为了快速制作,我正在尝试使用JBoss Tools 4.1 Hibernate插件。但我在第一回合就遇到了例外。

首先,物理数据库表如下:

 describe Teams ; 
 Name                           Null     Type                                                                                                                                                         
 ID                             NOT NULL NUMBER                                                                                                                                                                                        
 NAME                           NOT NULL VARCHAR2(20)                                                                                                                                                                                  
 COUNTRY                        NOT NULL VARCHAR2(20)   

 describe players;
 Name                           Null     Type                                                                                                                                                                                          
 ID                             NOT NULL NUMBER                                                                                                                                                                                        
 NAME                           NOT NULL VARCHAR2(20)                                                                                                                                                                                  
 NATIONALITY                    NOT NULL VARCHAR2(20) 

describe player_team;
Name                           Null     Type 
PLAYER_ID                      NOT NULL NUMBER                                                                                                                                                                                        
TEAM_ID                        NOT NULL NUMBER  

实体如下:

@Entity
@Table(name = "PLAYERS")
public class Players implements java.io.Serializable {

private BigDecimal id;
private String name;
private String nationality;
private Set<PlayerTeam> playerTeams = new HashSet<PlayerTeam>(0);

@Id
@Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
public BigDecimal getId() {
    return this.id;
}

@Column(name = "NAME", nullable = false, length = 20)
public String getName() {
    return this.name;
}

@Column(name = "NATIONALITY", nullable = false, length = 20)
public String getNationality() {
    return this.nationality;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "players")
public Set<PlayerTeam> getPlayerTeams() {
    return this.playerTeams;
}
  // setters go here but i deleted for readability 

 }


 @Entity
 @Table(name = "TEAMS")
 public class Teams implements java.io.Serializable {

private BigDecimal id;
private String name;
private String country;
private Set<PlayerTeam> playerTeams = new HashSet<PlayerTeam>(0);   

@Id
@Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
public BigDecimal getId() {
    return this.id;
}

@Column(name = "NAME", nullable = false, length = 20)
public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

@Column(name = "COUNTRY", nullable = false, length = 20)
public String getCountry() {
    return this.country;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "teams")
public Set<PlayerTeam> getPlayerTeams() {
    return this.playerTeams;
}

   // setters go here

 }

  @Embeddable
  public class PlayerTeamId implements java.io.Serializable {

private BigDecimal playerId;
private BigDecimal teamId;

@Column(name = "PLAYER_ID", nullable = false, precision = 22, scale = 0)
public BigDecimal getPlayerId() {
    return this.playerId;
}

public void setPlayerId(BigDecimal playerId) {
    this.playerId = playerId;
}

@Column(name = "TEAM_ID", nullable = false, precision = 22, scale = 0)
public BigDecimal getTeamId() {
    return this.teamId;
}

public void setTeamId(BigDecimal teamId) {
    this.teamId = teamId;
}

public boolean equals(Object other) {
    if ((this == other))
        return true;
    if ((other == null))
        return false;
    if (!(other instanceof PlayerTeamId))
        return false;
    PlayerTeamId castOther = (PlayerTeamId) other;

    return ((this.getPlayerId() == castOther.getPlayerId()) || (this
    .getPlayerId() != null && castOther.getPlayerId() != null && this   
            .getPlayerId().equals(castOther.getPlayerId())))
            && ((this.getTeamId() == castOther.getTeamId()) || (this
                    .getTeamId() != null && 
       castOther.getTeamId() != null && this                              
       .getTeamId().equals(castOther.getTeamId())));
}

public int hashCode() {
    int result = 17;

    result = 37 * result
            + (getPlayerId() == null ? 0 :  
        this.getPlayerId().hashCode());
    result = 37 * result
            + (getTeamId() == null ? 0 : this.getTeamId().hashCode());
    return result;
}

  }

然后我尝试在连接表中插入记录,如下所示:

            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.getTransaction().begin();       
    Players pl = (Players) session.load(Players.class, new BigDecimal(2));
    Teams tm = (Teams) session.load(Teams.class, new BigDecimal(25));
    PlayerTeam pt = new PlayerTeam();
    pt.setPlayers(pl);
    pt.setTeams(tm);
    session.save(pt);
    session.getTransaction().commit();

获得以下例外:

 org.hibernate.id.IdentifierGenerationException: null id generated for:class    
 business.PlayerTeam

最后是hibernate.cfg.xml

  <session-factory name="se">
    <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
    <property  
     name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
    <property name="hibernate.connection.password">LECTURE1</property>
    <property      
     name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
    <property name="hibernate.connection.username">lecture1</property>
    <property name="hibernate.default_schema">LECTURE1</property>
    <property name="hibernate.dialect">org.hibernate.dialect.Oracle8iDialect</property>
    <mapping class="business.Players" />
     <mapping class="business.PlayerTeam" />
    <mapping class="business.Teams" />
    <property name="current_session_context_class">thread</property>
    <property name="show_sql">true</property>
 </session-factory>

 Would you throw some light on this please ? thanks 

1 个答案:

答案 0 :(得分:1)

Hibernate中的每个实体都需要一个用@Id注释的ID列。您的PlayerTeam课程没有这样的专栏。如果您的PlayerTeam类只是一个连接表,它甚至不需要是一个实体。你可以这样做:

public class Players {

...

@ManyToMany(mappedBy="players", fetch=FetchType.LAZY)
private List<Teams> teams;

...

}

public class Teams {

...

@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(name="player_team", joinColumns={@JoinColumn(name="TEAM_ID")}, inverseJoinColumns={@JoinColumn(name="PLAYER_ID")})
private list<Players> players;

...

}

这将建立与Teams类作为拥有方的双向多对多关系。然后,您可以完全摆脱PlayerTeamId课程。

顺便说一句,我强烈建议您的班级名称是单数(例如玩家和团队而不是玩家和团队)