2

假设一支球队有很多球员。使用 JPA/休眠。Postgres 9.1。GenerationType.IDENTITY(Postgres 在 int 列上使用序列,如 Oracle)。在新插入时,当我 em.persist() 时,我在子表上得到一个非空错误(在我非常非常轻微混淆的代码中的播放器表......更改了名称以保护无辜。:) 错误信息如下.

父表

@Entity
@Table(name = "team")
public class Team implements Serializable {
    @Id
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    @Column(name = "teamid")
    private Long teamid;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "teamid", fetch = FetchType.LAZY)
    private Collection<Player> playerList;

子表

@Entity
@Table(name = "player")
@XmlRootElement
public class Player implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "playerid")
    private Long playerid;
    @JoinColumn(name = "teamid", referencedColumnName = "teamid")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Team teamid;

persistence.xml 很好的衡量标准:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="ELS_Soulard_PU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/ElsDev1Pool</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
  </persistence-unit>
</persistence>

错误信息:

INFO: THROWABLE INFO: org.postgresql.util.PSQLException: ERROR: null value in column "teamid" violates not-null constraint
INFO: Team Controller persistence exception THROWABLE MESSAGE: could not insert: [com.mydomainblahblahblah.persistence.entity.Player]

请注意,如果我将玩家排除在等式之外,即在“团队”类中,玩家属性的值设置为 null(我注释掉将玩家列表添加到属性的代码),数据将成功插入团队表。问题全在球员身上。(问问多伦多枫叶队的老板就知道了。:p)。

可能是导致问题的 GenerationType.IDENTITY 吗?即在事务结束之前没有返回父表中的teamid,所以它不能作为FK放在玩家表中?如果是这样,除了使用不同的生成类型之外,是否有任何补救措施?我喜欢使用数据库序列(更多控制恕我直言)。

序列生成类型会更好还是同样的问题?但我确信必须有某种方法可以做到这一点。没有吗?:/


将 ID 更改为这样(即让 hibernate 生成它们):

@Id
@Column(name = "teamid")
private Long teamid;

现在我收到此错误:

INFO: EXCEPTION CLASS NAME: javax.persistence.PersistenceException
INFO: THROWABLE CLASS NAME: org.hibernate.id.IdentifierGenerationException

啊!

4

1 回答 1

3

所以这里唯一的错误是我对表连接和 JPA 类型 ORM 的工作原理的理解(我以前使用过 MyBatis,所以还在学习 JPA)。事实证明,即使直觉上你会认为我可以将数据添加到我的团队类中,包括我的球员的数组列表,然后将其持久化,但你不能。您必须首先坚持团队,然后将团队依次添加到每个玩家中,然后一次坚持一个。所以本质上,这段代码没有任何问题。问题出在椅子和电脑之间。:/ 它已经被纠正了。

于 2012-05-12T05:51:15.253 回答