2010-11-11 84 views
1

我遇到了与JPA不同的奇怪错误,它不是持久性提供程序特定的。我使用的是JPA 2.0,我正在使用生成的模式。由JPA生成的错误SQL语句

简而言之:生成的模式包含一个包含三列的连接表,但生成的插入语句将该表视为只有两列。

这里是映射:

@Entity 
@Table(name = "Game") 
public class MatchEntity implements Match, Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @ManyToOne(targetEntity = ClubEntity.class) 
    private Club homeTeam; 

    @ManyToOne(targetEntity = ClubEntity.class) 
    private Club awayTeam; 

    @ManyToMany(targetEntity = PlayerEntity.class) 
    private Collection<Player> homeTeamPlayers; 

    @ManyToMany(targetEntity = PlayerEntity.class) 
    private Collection<Player> awayTeamPlayers; 

    private String location; 

    @Temporal(value = TemporalType.DATE) 
    @Column(name = "Match_Date") 
    private Date date; 

    /* constructor, getters and setters follow */ 
} 


@Entity 
@Table(name = "Club") 
public class ClubEntity implements Club, Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 

    @OneToMany(fetch = FetchType.EAGER, targetEntity = PlayerEntity.class, 
    mappedBy = "club") 
    private Collection<Player> players = new ArrayList<Player>(); 

    private String fieldName; 

    private Boolean archived; 

    /* constructor, getters and setters follow */ 
} 

@Entity 
@Table(name = "PLAYER") 
public class PlayerEntity implements Player, Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String firstName; 

    private String surname; 

    @Temporal(value = TemporalType.DATE) 
    private Date birthDate; 

    @Column(name = "pos")  
    @Enumerated(EnumType.ORDINAL) 
    private Position position; 

    private Integer number; 

    private Boolean archived; 

    @ManyToOne(targetEntity = ClubEntity.class, fetch = FetchType.EAGER) 
    private Club club; 


    /* constructor, getters and setters follow */ 
} 

从这些映射,以下模式被创建:

create table Club (id bigint generated by default as identity (start with 1), archived bit, fieldName varchar(255) not null, name varchar(255) not null, primary key (id)) 
create table Game (id bigint generated by default as identity (start with 1), Match_Date date, location varchar(255), awayTeam_id bigint, homeTeam_id bigint, primary key (id)) 
create table Game_PLAYER (Game_id bigint not null, homeTeamPlayers_id bigint not null, awayTeamPlayers_id bigint not null) 
create table PLAYER (id bigint generated by default as identity (start with 1), archived bit, birthDate date, firstName varchar(255) not null, number integer, pos integer, surname varchar(255) not null, club_id bigint, primary key (id)) 
alter table Game add constraint FK21C0123B2A3B9E foreign key (homeTeam_id) references Club 
alter table Game add constraint FK21C012F5972EAF foreign key (awayTeam_id) references Club 
alter table Game_PLAYER add constraint FK267CF3AE6AE1D889 foreign key (Game_id) references Game 
alter table Game_PLAYER add constraint FK267CF3AED51EDECF foreign key (homeTeamPlayers_id) references PLAYER 
alter table Game_PLAYER add constraint FK267CF3AE6CBE869E foreign key (awayTeamPlayers_id) references PLAYER 
alter table PLAYER add constraint FK8CD18EE13F2C6C64 foreign key (club_id) references Club 

这条线是非常重要的 - 这是连接表。

create table Game_PLAYER (Game_id bigint not null, homeTeamPlayers_id bigint not null, awayTeamPlayers_id bigint not null) 

当我试图坚持游戏实体(MatchEntity.java),出现这种情况:

insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?) 
Hibernate: insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?) 
binding '2' to parameter: 1 
binding '1' to parameter: 2 
reusing prepared statement 
insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?) 
Hibernate: insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?) 
binding '2' to parameter: 1 
binding '2' to parameter: 2 
done inserting collection: 2 rows inserted 
Inserting collection: [football.model.entities.MatchEntity.homeTeamPlayers#2] 
Executing batch size: 2 
about to close PreparedStatement (open PreparedStatements: 1, globally: 1) 
Could not execute JDBC batch update [insert into Game_PLAYER (Game_id, awayTeamPlayers_id) values (?, ?)] 

JPA试图插入两排连接表,每一个影响只有两三个列。

我曾尝试:

  • 在映射摆脱接口完全
  • 定义一个明确的连接表
  • 使用,而不是休眠

OpenJPA中亦没有解决问题。

编辑:用于预先抓取:

@Transactional(readOnly = true) 
    public Collection<Match> findAll() {   
     em.createQuery("SELECT m FROM MatchEntity m " 
      + "JOIN FETCH m.homeTeamPlayers", MatchEntity.class).getResultList(); 
     List<MatchEntity> rList = em.createQuery("SELECT m FROM MatchEntity m " 
      + "JOIN FETCH m.awayTeamPlayers", MatchEntity.class).getResultList(); 
     Collection<Match> result = new ArrayList<Match>(rList); 
     return result; 
    } 

回答

1

也许你需要不同的连接表为homeTeamPlayersawayTeamPlayers

@ManyToMany(targetEntity = PlayerEntity.class) 
@JoinTable(name = "Game_HomeTeamPlayers") 
private Collection<Player> homeTeamPlayers; 

@ManyToMany(targetEntity = PlayerEntity.class) 
@JoinTable(name = "Game_AwayTeamPlayers") 
private Collection<Player> awayTeamPlayers; 
+0

我试过了,但是有两个连接表,我得到的重复的实例选择MatchEntity类。重复数量取决于两个连接表中的行数(匹配中的玩家数量)。例如,Game_AwayTeamPlayers中的3行和Game_HomeTeamPlayers中的4行会导致此游戏的3个实例返回select。 – prasopes 2010-11-11 14:46:30

+0

@stoupa:也许你在这些关系上有'fetch = EAGER'? – axtavt 2010-11-11 14:50:56

+0

@axtavt:我没有为这些打开热切的提取,但我正在做他们的联合提取。你能否告诉我如何进行急切的提取? – prasopes 2010-11-11 14:59:14