如何使用@IdClass正确映射多对一关系?

时间:2018-09-17 16:00:41

标签: java hibernate

我想在Hibernate中创建一个带有组合主键的表。主键的一部分是自动生成的值,另一部分以多对一的关系引用另一个表的主键。

我没有使用@EmbeddedId,因为我没有设法使工作在@Embeddable类内自动生成。所以最后我决定使用@IdClass。

经过研究后,我想到了下一个代码:

@Entity
@IdClass(PartidaId.class)
@Table(name = "partida", schema="trueskill")
public class Partida implements Serializable {

    private static final long serialVersionUID = 659832134987666699L;

    @Id
    @GeneratedValue
    @Column(name ="partida_id")
    private Integer partida_id;

    @Id
    @Column(name = "jugador_id", insertable = false, updatable = false)
    private Integer jugador_id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "jugador_id", referencedColumnName = "id")
    private Jugador jugador;

    @Column(name = "PUNTOS")
    private int puntos;

    ....
}

public class PartidaId implements Serializable {

    private static final long serialVersionUID = 997366452999076354L;

    private Integer jugador_id; 
    private Integer partida_id;
    ...
}

它可以正确编译,但是当我尝试保留一个实体时:

Jugador p1 = new Jugador("Player1");
Partida part1 = new Partida(7, p1);
em.persist(p1);
em.persist(part1);

我收到以下错误:

17:54:31,369 DEBUG [org.hibernate.SQL] - insert into trueskill.partida (jugador_id, PUNTOS, partida_id) values (?, ?, ?)
17:54:31,374 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [INTEGER] - [1]
17:54:31,374 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [2] as [INTEGER] - [7]
17:54:31,374 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [3] as [INTEGER] - [null]
17:54:31,374 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [4] as [INTEGER] - [4]
17:54:31,390 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] - SQL Error: 20000, SQLState: XCL14
17:54:31,390 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] - Die Spaltenposition '4' befindet sich außerhalb des Bereichs. Die Anzahl der Spalten für dieses ResultSet liegt bei '3'.
17:54:31,392 ERROR [org.hibernate.internal.ExceptionMapperStandardImpl] - HHH000346: Error during managed flush [org.hibernate.exception.GenericJDBCException: could not insert: [model.Partida]]

问题在于,当只有3个参数时,它将尝试插入一个额外的“空”参数。有人可以告诉我为什么会这样吗?

先谢谢您!

1 个答案:

答案 0 :(得分:0)

您在partida实体中不需要整数jugador_id。您可能在jugador实体中有一个@Id,并与partida类的@oneToMany关系中进行了映射。 删除此内容:

ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]

ORIGINAL LIST
x≡3(mod4)
x≡4(mod5)


RETURNED AS A LIST
["x\u22613(mod4)", "x\u22614(mod5)"]


RETURNED AND ACCESSED INDIVIDUALLY
x≡3(mod4)
x≡4(mod5)

使用此:

@Id
@Column(name = "jugador_id", insertable = false, updatable = false)
private Integer jugador_id;

确保在Jugador课堂上有类似的内容。

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "jugador_id", referencedColumnName = "id")
private Jugador jugador;