java - JPA生成错误的SQL语句

标签 java orm jpa

我在 JPA 中遇到了一个奇怪的错误,该错误不是特定于持久性提供程序的。我正在使用 JPA 2.0,并且正在使用生成的架构。

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

以下是映射:

@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 尝试向连接表插入两行,每行仅影响三列中的两列。

我尝试过的:

  • 完全摆脱映射中的接口(interface)
  • 定义显式连接表
  • 使用 OpenJPA 代替 Hibernate

都没有解决问题。

编辑:急切获取的代码:

    @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;
    }

最佳答案

也许您需要为 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; 

关于java - JPA生成错误的SQL语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4155352/

相关文章:

java - 使用按钮停止 for 循环

java - 多线程Java客户端服务器问题

python - 多对多表和初始化字段

android - 具有多列的 ORMLite 自定义数据持久性

java - 无法使用 Microsoft SQL Server 和 Javax.Persistence 解析 Java 中的列 [名称]

java - RxJava2,显式完成冷源(Flowable)

java - 如何学习用 Java 设计应用程序

php - PHP 中是否有类似于 mongoid 的 MongoDB ORM?

hibernate - JPA 注释中的 inverse=true

java - 如何使用 JPA Criteria API/Hibernate 按 Case 语句分组