一个类似@Entity和@Embeddable的类 [英] A class that behaves like @Entity and @Embeddable

查看:73
本文介绍了一个类似@Entity和@Embeddable的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Team和Player类之间有单向的@OneToMany关系。我想在你的玩家中保存一个Team对象。玩家的标识符IS COMPOUND by Team外键和列表索引如下。我有这样一个映射,因为我需要保存团队和玩家同时进行。

  @Entity 
public class Team {

@Id
@GeneratedValue
private Integer id;
$ b $ @CollectionOfElements
@JoinTable(
name =PLAYER,
joinColumns = @ JoinColumn(name =TEAM_ID))
@IndexColumn name =PLAYER_INDEX)
私人列表< Player> playerList = new ArrayList< Player>();

}

@Embeddable
public class Player {

//玩家的获取者和设置者的

}

因此,如果我使用以下内容

  Team team = new Team(); 

team.getPlayerList()。add(new Player());
team.getPlayerList()。add(new Player());

session.save(team); // 有用!

无论您使用@CollectionsOfElements,Player类都需要@Embeddable批注,而不是@Entity。 JPA不允许同时使用@Entity和@Embeddable。玩家也是一个@实体 - 它与其他实体有关系。



有人有关于我可以通过使用CascadeType保存团队和玩家(单向关系)的想法.PERSIST与Player类中的@Entity而不是@Embeddable?

请记住,COMPOUND主键需要在保存前分配,但Team的标识符和PlayerList索引位置可以扮演Player的复合主键的角色



问候,

解决方案

以下解决方案显示了由Team和位置组成的组合键在该队的球员名单中。

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>();

私人字符串名称;

保护团队(){}

公共团队(字符串名称){
this.name = name;
}

public boolean addPlayer(Player player){
boolean result = players.add(player);
if(result){
player.setPlayerId(new PlayerId(this,players.size() - 1));
}
返回结果;
}

公共列表< Player> getPlayers(){
返回玩家;
}

@Override
public String toString(){
返回新的ToStringBuilder(this,ToStringStyle.SHORT_PREFIX_STYLE).append(name,name).append (玩家,玩家).toString();
}
}

Player.java

  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实现Serializable {

@Id private PlayerId id;

@Version private int version;

void setPlayerId(PlayerId id){
this.id = id;

$ b @Override
public String toString(){
返回新的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实现Serializable {

@ManyToOne
私人团队;

@Column(name =PLAYER_IDX,insertable = false,updatable = false)
private int number;

受保护的PlayerId(){}

PlayerId(团队团队,int数){
this.team = team;
this.number = number;
}

public int getNumber(){
return number;

$ b @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;
返回other.team.equals(this.team)&& other.number == this.number;
}
返回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(新玩家());
team.addPlayer(新玩家());

AnnotationConfiguration配置=新的AnnotationConfiguration();
configuration.addAnnotatedClass(Team.class);
configuration.addAnnotatedClass(Player.class);
configuration.configure();

SessionFactory sessionFactory = configuration.buildSessionFactory();
会议会议;
session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
session.save(team);
transaction.commit();
session.close();

session = sessionFactory.openSession();
@SuppressWarnings(unchecked)列表< 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整数不为空,
整数不为空,
team_id bigint,
主键(PLAYER_IDX,team_id)

12:37:17,796 DEBUG [SchemaExport,SchemaExport.execute]
create table团队(
默认情况下生成的id bigint作为标识(从1开始),
name varchar(255),
version integer不为null,
主键(id)

12:37:17,796 DEBUG [SchemaExport,SchemaExport.execute]
alter table Player
add constraint FK8EA38701AA5DECBA
外键(team_id)
引用Team
12:37: 17,812信息[SchemaExport,SchemaExport.importScript]执行导入脚本:/import.sql
12:37:17,812 INFO [SchemaExport,SchemaExport.execute] schema e xport complete
12:37:17,859 DEBUG [SQL,SQLStatementLogger.logStatement]

插入
Team
(id,name,version)
values
(null,?,?)
12:37:17,875调试[SQL,SQLStatementLogger.logStatement]
调用标识()
12:37:17,875 DEBUG [SQL,SQLStatementLogger .logStatement]
select
player_.PLAYER_IDX,
player_.team_id,
player_.version as version1_
from
Player player_
其中
player_.PLAYER_IDX =?
和player_.team_id =?
12:37:17,890 DEBUG [SQL,SQLStatementLogger.logStatement]
选择
player_.PLAYER_IDX,
player_.team_id,
player_.version as version1_
from
Player player_
其中
player_.PLAYER_IDX =?
和player_.team_id =?
12:37:17,890 DEBUG [SQL,SQLStatementLogger.logStatement]
插入

播放器
(版本,PLAYER_IDX,team_id)

(?,?,?)
12:37:17,890 DEBUG [SQL,SQLStatementLogger.logStatement]

插入
Player
(版本,PLAYER_IDX,
$($,$,$)
12:37:17,906 DEBUG [SQL,SQLStatementLogger.logStatement]
选择
this_.id作为id0_0_,
this_.name as name0_0_,
this_.version as version0_0_
from
Team this_
12:37:17,937 DEBUG [SQL,SQLStatementLogger.logStatement]
选择
players0_.team_id作为team3_1_,
作为PLAYER1_1_的players0_.PLAYER_IDX,
作为PLAYER1_1_0_的球员0_.PLAYER_IDX,
作为team3_1_0_的球员0_.team_id,
players0_.version作为版本1_0_
来自
玩家玩家0_
其中
players0_.team_id =?
Team [name = My Team,players = [Player [number = 0],Player [number = 1]]]

最后一行显示 Team Player的 toString ,它显示了数字是如何分配的(列表的索引)。其他实体可以引用玩家(通过team_id和player_idx)。


I have a one way @OneToMany relationship between a Team and Player class. I would like to save a Team object among your Players. Player's identifier IS COMPOUND by Team foreign key and list index as follows. I have a mapping like this one because i need to save Team and your Players ate the same time.

@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

}

So if i use the following

Team team = new Team();

team.getPlayerList().add(new Player());
team.getPlayerList().add(new Player());

session.save(team); // It works!

It happens whether you use @CollectionsOfElements, Player class need a @Embeddable annotation, not a @Entity. JPA does not allows @Entity and @Embeddable at the same time. Player is also a @Entity - it has relationship with other entities.

Has someone an idea about i could save a Team and a Player (ONE WAY RELATIONSHIP) by using CascadeType.PERSIST with @Entity in the Player class instead of @Embeddable ?

Remember that COMPOUND primary key needs to be assigned before saving but Team's identifier and PlayerList index position could play the role of Player's compound primary key

regards,

解决方案

The below solution shows a composite key for Player that consists of Team and the position in the list of players in that team. Saves cascade from team to players.

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();
    }
}

Player.java

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();
    }

}

This test below:

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);

gives the following log output:

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]]]

The last line shows the toString for Team and Player, which shows how the numbers are assigned (the index of the list). Other entities can refer the Player (by team_id and player_idx).

这篇关于一个类似@Entity和@Embeddable的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆