我在Team和Player类之间有一种@OneToMany关系。我想在您的玩家之间保存一个Team对象。玩家的标识符由团队外键和列表索引组成,如下所示。我有一个这样的映射,因为我需要保存Team和您的Players同时吃饭。
@Entity
public class Team {
@Id
@GeneratedValue
private Integer id;
@CollectionOfElements
@JoinTable(
name="PLAYER",
joinColumns=@JoinColumn(name="TEAM_ID"))
@IndexColumn(name="PLAYER_INDEX")
private List<Player> playerList = new ArrayList<Player>();
}
@Embeddable
public class Player {
// Player's getter's and setter's
}
所以,如果我使用以下
Team team = new Team();
team.getPlayerList().add(new Player());
team.getPlayerList().add(new Player());
session.save(team); // It works!
无论是否使用@
CollectionsOfElements,Player类都需要一个@Embeddable注释,而不是一个@Entity,这会发生。JPA不允许同时使用@Entity和@Embeddable。Player也是@Entity-
它与其他实体有关系。
有没有关于我可以通过在Player类中将CascadeType.PERSIST与@Entity而不是@Embeddable一起使用来保存团队和玩家(单向关系)的想法?
请记住,在保存之前需要分配COMPOUND主键,但是Team的标识符和PlayerList索引位置可以扮演Player的复合主键
问候,
以下解决方案显示了一个由玩家组成的复合键,该键由团队和该团队中的玩家列表中的位置组成。从团队到球员节省级联。
Team.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Version;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.hibernate.annotations.IndexColumn;
@Entity
public class Team implements Serializable {
@Id @GeneratedValue private Long id;
@Version private int version;
@OneToMany(cascade=CascadeType.ALL, mappedBy="id.team")
@IndexColumn(name="PLAYER_IDX")
private List<Player> players = new ArrayList<Player>();
private String name;
protected Team() {}
public Team(String name) {
this.name = name;
}
public boolean addPlayer(Player player) {
boolean result = players.add(player);
if (result) {
player.setPlayerId(new PlayerId(this, players.size() - 1));
}
return result;
}
public List<Player> getPlayers() {
return players;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("name", name).append("players", players).toString();
}
}
播放器
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
@Entity
public class Player implements Serializable {
@Id private PlayerId id;
@Version private int version;
void setPlayerId(PlayerId id) {
this.id = id;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("number", id.getNumber()).toString();
}
}
PlayerId.java
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;
import org.apache.commons.lang.builder.HashCodeBuilder;
@Embeddable
public class PlayerId implements Serializable {
@ManyToOne
private Team team;
@Column(name="PLAYER_IDX", insertable=false, updatable=false)
private int number;
protected PlayerId() {}
PlayerId(Team team, int number) {
this.team = team;
this.number = number;
}
public int getNumber() {
return number;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (obj == this) {
return true;
} if (obj instanceof PlayerId) {
PlayerId other = (PlayerId) obj;
return other.team.equals(this.team) && other.number == this.number;
}
return false;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(team).append(number).toHashCode();
}
}
此测试如下:
public void testPersistTeamAndPlayers() throws Exception {
Team team = new Team("My Team");
team.addPlayer(new Player());
team.addPlayer(new Player());
AnnotationConfiguration configuration = new AnnotationConfiguration();
configuration.addAnnotatedClass(Team.class);
configuration.addAnnotatedClass(Player.class);
configuration.configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session;
session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
session.save(team);
transaction.commit();
session.close();
session = sessionFactory.openSession();
@SuppressWarnings("unchecked") List<Team> list = session.createCriteria(Team.class).list();
assertEquals(1, list.size());
Team persisted = list.get(0);
System.out.println(persisted);
给出以下日志输出:
12:37:17,796 DEBUG [SchemaExport, SchemaExport.execute]
create table Player (
PLAYER_IDX integer not null,
version integer not null,
team_id bigint,
primary key (PLAYER_IDX, team_id)
)
12:37:17,796 DEBUG [SchemaExport, SchemaExport.execute]
create table Team (
id bigint generated by default as identity (start with 1),
name varchar(255),
version integer not null,
primary key (id)
)
12:37:17,796 DEBUG [SchemaExport, SchemaExport.execute]
alter table Player
add constraint FK8EA38701AA5DECBA
foreign key (team_id)
references Team
12:37:17,812 INFO [SchemaExport, SchemaExport.importScript] Executing import script: /import.sql
12:37:17,812 INFO [SchemaExport, SchemaExport.execute] schema export complete
12:37:17,859 DEBUG [SQL, SQLStatementLogger.logStatement]
insert
into
Team
(id, name, version)
values
(null, ?, ?)
12:37:17,875 DEBUG [SQL, SQLStatementLogger.logStatement]
call identity()
12:37:17,875 DEBUG [SQL, SQLStatementLogger.logStatement]
select
player_.PLAYER_IDX,
player_.team_id,
player_.version as version1_
from
Player player_
where
player_.PLAYER_IDX=?
and player_.team_id=?
12:37:17,890 DEBUG [SQL, SQLStatementLogger.logStatement]
select
player_.PLAYER_IDX,
player_.team_id,
player_.version as version1_
from
Player player_
where
player_.PLAYER_IDX=?
and player_.team_id=?
12:37:17,890 DEBUG [SQL, SQLStatementLogger.logStatement]
insert
into
Player
(version, PLAYER_IDX, team_id)
values
(?, ?, ?)
12:37:17,890 DEBUG [SQL, SQLStatementLogger.logStatement]
insert
into
Player
(version, PLAYER_IDX, team_id)
values
(?, ?, ?)
12:37:17,906 DEBUG [SQL, SQLStatementLogger.logStatement]
select
this_.id as id0_0_,
this_.name as name0_0_,
this_.version as version0_0_
from
Team this_
12:37:17,937 DEBUG [SQL, SQLStatementLogger.logStatement]
select
players0_.team_id as team3_1_,
players0_.PLAYER_IDX as PLAYER1_1_,
players0_.PLAYER_IDX as PLAYER1_1_0_,
players0_.team_id as team3_1_0_,
players0_.version as version1_0_
from
Player players0_
where
players0_.team_id=?
Team[name=My Team,players=[Player[number=0], Player[number=1]]]
最后一行显示toString
for
Team
和Player
,它显示如何分配数字(列表的索引)。其他实体可以引用玩家(通过team_id和player_idx)。
问题内容: 我有班钱是@Embeddable 当我在实体中多次使用它时,一切正常。例如 上面的代码完美地工作。 现在,当我有另一个@Embeddable想要在其中包含Money实例并且该@Embeddable被实体多次使用时,就会出现问题。例: 可嵌入 public class ReportCostValues implements Serializable { 实体 public class R
问题内容: 我想知道是否无论如何都要使JformattedTextField或jtextField表现得像自动柜员机钱输入。我的意思是,您从右至左输入,说输入10,您需要再按2再加上0,这样它将是10.00。程序从右到左输入时会自动输入小数点?如果未输入2 0,则为.10。这可能吗?如果我想使用该字符串进行计算,该如何返回给我?我尝试了抽象格式化程序,但是效果不是很好。我想用它来输入客户收到的金额
当我使用命令列出所有分支时,我会看到的输出。 命令应该显示分支列表,就像对文件所做的那样。 这是我得到的输出: 如何获得git分支的默认行为?是什么导致分页输出? 我将ZSH与(其中Git没有任何内容)一起使用,我的如下所示:
问题内容: 我正在寻找一种创建表单的方法,按Enter键可使焦点移至页面上的“下一个”表单元素。我一直在网上找到的解决方案是… 不幸的是,这似乎仅在IE中有效。因此,这个问题的实质是,是否有人知道适用于FF和Chrome的解决方案?另外,我宁愿不必将 onkeydown 事件添加到表单元素本身,但是如果那是唯一的方法,则必须这样做。 编辑:另外,我已经看到人们提出了这样的问题,即这不是好样式,因为
我正在阅读有关流的信息,发现我们可以使用setvbuf()函数来控制流......它写的是在行缓冲模式中,当遇到换行符时流将数据发送到文件中,在无缓冲状态下没有缓冲......所以我写了以下代码...... 所以我认为,因为这些是无缓冲流,所以输入应该在我写入屏幕后立即发送到标准输出。。。但程序在写入每一行后等待我按enter键,然后屏幕上只显示输出(由于fwrite)。。。我的问题是,当这些是无
问题内容: 在我的Web应用程序中,我有一个后台服务。该服务使用Generator类,该类包含Engine类,并且配置为使用多个线程并接受GeneratorTasks。 Engine类需要很长时间进行初始化,因此理想情况下,我希望每个线程仅初始化一次。我不能仅仅使它成为一个单例实例,因为该实例不能在多个线程之间共享(它依赖于顺序处理)。不过,在完成处理任务之后,可以很好地重用实例。 我当时正在考虑