为了快速制作,我正在尝试使用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
答案 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
课程。
顺便说一句,我强烈建议您的班级名称是单数(例如玩家和团队而不是玩家和团队)