【问题标题】:Trying to write two tables with one to one relationship but the joinColumn comes up null尝试编写两个具有一对一关系的表,但 joinColumn 出现 null
【发布时间】:2015-12-18 22:31:54
【问题描述】:

我在网页上有一个表单,需要将其放入两个不同的表中,即 appinfo 和首选项。 appinfo 和preferences 都有一个自动生成的id。 appinfo 还包含一个名为“preferenceid”的首选项的外键。我需要使用 hibernate 将首选项表的自动生成的 id 输入到此字段中。

我使用 SpringMVC 创建了两个 POJO,我正在尝试将它们写入数据库。基本格式是:

Preferences.java:

@Entity
@Table (name ="preferences")
public class Preferences implements Serializable {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int preferencesid;
    (Other variables with getters and setters)

    @OneToOne
    @JoinColumn(name="preferencesid", referencedColumnName="preferenceid")
    private AppInfo ai;
    public AppInfo getAi() {
        return ai;
    }

    public void setAi(AppInfo ai) {
        this.ai = ai;
    }

AppInfo.java

@Entity
@Table (name ="appinfo")
public class AppInfo implements Serializable {
    @Id
    @Column(name = "appuserid")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    @OneToOne
    @JoinColumn(name="preferenceid", referencedColumnName="preferencesid")
    private Preferences p;
    (Other variables and getters and setters)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Preferences getP() {
        return p;
    }

    public void setP(Preferences p) {
        this.p = p;
    }

当我保存数据时,Preferences 工作正常,它会自动生成它的 id 值。但是我的 AppInfo 没有正确获取preferencesid;它只有空值。如果我更改表以允许空值,则两者都将插入所有正确的信息,除了 AppInfo 表中的preferencesid 现在为空。

【问题讨论】:

  • 对不起,如果我不是很清楚。我在网页上有一个表单,需要将其放入两个不同的表中,即 appinfo 和首选项。 appinfo 和preferences 都有一个自动生成的id。 appinfo 还包含一个名为“preferenceid”的首选项的外键。我需要使用 hibernate 将首选项表的自动生成的 id 输入到此字段中。
  • 嗨@MMX,把它放在你的问题上。这是您需要更新的地方

标签: java mysql hibernate jpa one-to-one


【解决方案1】:

选项 1

如果您希望AppInfo 持有Preferences 的外键,而Preferences 不需要AppInfo 的外键,那么 改变如下。

从首选项中删除映射

     @Entity
     @Table (name ="preferences")
     public class Preferences implements Serializable {

     //    @OneToOne(mappedBy)
     //    @JoinColumn(name="preferencesid", referencedColumnName="preferenceid")
     //    private AppInfo ai;

并在AppInfo中指定级联类型

@Entity
@Table (name ="appinfo")
public class AppInfo implements Serializable {

    @OneToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name="preferenceid", referencedColumnName="preferencesid")
    private Preferences p;

如果你想做cascade = CascadeType.ALL 然后,当您需要保存实例时,如下所示。

    AppInfo ai = new AppInfo();     
    Preferences p = new Preferences();

    ai.setP(p);     
    session.persist(ai); 

如果设置为cascade = CascadeType.ALL,则可以使用session.save(ai);


选项 2

如果您希望两个表相互保存一个外键,那么 改变如下。

@Entity
@Table (name ="appinfo")
public class AppInfo implements Serializable {
    ....
    @OneToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name="preferenceid")
    private Preferences p;



@Entity
@Table (name ="preferences")
public class Preferences implements Serializable {
    ....
    @OneToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name="appuserid")
    private AppInfo ai;

如果需要,将级联类型更改为CascadeType.All。 保存实例时,

    AppInfo ai = new AppInfo();     
    Preferences p = new Preferences();

    ai.setP(p);     
    p.setAi(ai);

    session.persist(ai);

希望这会有所帮助。

【讨论】:

  • 哇,解决了!看起来我犯的一个大错误是没有 ai.setP(p); session.persist(ai);而是 session.persist(ai); session.persist(p)。非常感谢您的帮助。
  • 您还需要cascade 属性。我将其设置为PERSIST,这就是我使用session.persist(ai) 的原因。阅读有关级联类型的更多信息,如果您使用ALL 级联选项或休眠特定的保存或更新级联选项,则可以使用session.save(ai)
  • 是的,我之前尝试过使用cascade,但是没有在ai中设置p,它不起作用。我会像你建议的那样研究不同的级联类型,当我尝试设置级联时,我将其设置为 ALL。再次感谢您的帮助
  • 我有,但由于我是新手,它显然不会在我有 15 个声望点之前显示?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多