【问题标题】:JPA Field doesn't have a default value, one to one relationJPA 字段没有默认值,一对一关系
【发布时间】:2016-12-28 22:37:04
【问题描述】:

我在 ECLIPSELINK 中的一对一关系有问题,关系是用户和代理之间的关系,错误是

异常 [EclipseLink-4002](Eclipse 持久性服务 - 2.5.0.v20130507-3faac2b):org.eclipse.persistence.exceptions.DatabaseException 内部 异常:java.sql.SQLException:字段 'userId' 没有 默认值 错误代码:1364 调用:INSERT INTO AGENT (ADDRESS, NOM, PRENOM) VALUES (?, ?, ?) bind => [3 个参数绑定]

class diagram

database implementation

这是我的 JPA 代码

@Entity
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private int active;
    private String email;
    private String password;
    //bi-directional one-to-one association to Agent
    @OneToOne(mappedBy="user",cascade=CascadeType.PERSIST)
    private Agent agent;
    //....


@Entity
@NamedQuery(name="Agent.findAll", query="SELECT a FROM Agent a")
public class Agent implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    private String address;

    private String nom;

    private String prenom;

    //bi-directional one-to-one association to User
    @OneToOne(cascade=CascadeType.PERSIST)
    @PrimaryKeyJoinColumn(name="userId")
    private User user;
//...
}

//the code that contains the error
        Agent agent = new Agent();
        agent.setAddress("addresse 1");
        agent.setNom("nom1");
        agent.setPrenom("prenom 1");
        User user = new User();
        user.setActive(1);
        user.setEmail("test@mail.local");
        user.setPassword("p@ssword");
        agent.setUser(user);
        agentService.add(agent);

【问题讨论】:

  • 你没有使用 Hibernate。您正在使用 EclipseLink。
  • 但是导入的都是import javax.persistence.*;
  • 是的,这是标准的 JPA 包。 Hibernate 和 EclipseLink 是 JPA 规范的两种不同实现。
  • 我该如何解决这个错误?
  • 你不需要agentService.add(user)还是userService.add(user)?

标签: java jpa jakarta-ee eclipselink


【解决方案1】:

通过将“id”字段设置为“IDENTITY”策略,在数据存储中,此列必须类似于 AUTO_INCREMENT (MySQL) 或 SERIALIDENTITY。这就是 IDENTITY 策略的先决条件(如果您让 JPA 提供程序生成模式,则默认情况下会得到)。

如果不是,则要么将列类型更改为这样,将策略更改为在运行时生成值的东西(不在数据存储)。

【讨论】:

    【解决方案2】:

    当我使用PrimaryKeyJoinColumn 时,我已经知道EclipseLink 的这种问题。

    Agent 实体中,您将id 定义为PK:

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    

    但您还定义了另一个带有 PK 的字段(userId 这也是用户表上的外键):

    //bi-directional one-to-one association to User
    @OneToOne(cascade=CascadeType.PERSIST)
    @PrimaryKeyJoinColumn(name="userId")
    private User user;
    


    当我看到你的数据库图时,我不确定这是你的目标。

    如果我看不正确并且您确实想这样做,您可以尝试使用 Embeddable 对象来承载 PK 的必填字段。
    如果您总是有例外,您可以通过首先单独保留用户,然后将其设置为代理并保留代理来绕过该问题。

    如果您不需要在Agent 中包含此复合键,请将@PrimaryKeyJoinColumn 替换为@JoinColumn

    取而代之的是:

    //bi-directional one-to-one association to User
    @OneToOne(cascade=CascadeType.PERSIST)
    @PrimaryKeyJoinColumn(name="userId")
    private User user;
    

    这样做:

    //bi-directional one-to-one association to User
    @OneToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="userId")
    private User user;
    

    【讨论】:

    • 我已将 @PrimaryKeyJoinColumn(name="userId") 替换为 @JoinColumn(name="userId") ,现在的错误是字段 userId 存在多个可写映射,但它没有不再部署
    • 在你实际的Agent映射中,userId被映射一次。如果您有另一个映射,您应该编辑您的帖子并显示所有相关信息。
    猜你喜欢
    • 1970-01-01
    • 2018-09-27
    • 2018-03-27
    • 2015-04-23
    • 2023-03-08
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 2019-11-23
    相关资源
    最近更新 更多