JSF JPA @OneToMany 持久性中没有引用 id

No reference id in JSF JPA @OneToMany persistence

我有 2 个 JPA 实体 XparentXchild,映射有注释 @OneToMany、控制器 class Xcontroller 和 JSF 按钮“持久化” ”。到目前为止,单击“坚持”工作正常,但是 Xchild 记录中的字段 Xchild.xparent_id 中没有设置引用 ID。

据我所知,所有注释都是正确的,因为它在控制器 class 中使用 List<Xchild> 循环生成记录,而 xparent 调用 persist(xparent) ] 目的。

如何正确设置字段 Xchild.parent_id

当前Xparent关系结果:
"id""text"
"1" "Parent"

当前 Xchild 关系结果:
"id" "text" "xparent_id"
“1”"Child 1"“”
“2”"Child 2"“”
“3”"Child 3"“”
“4”"Child 4"“”

预期 Xchild 关系(id 来自 Xparent:
"id" "text" "xparent_id"
"1" "Child 1" "1"
"2" "Child 2" "1"
"3" "Child 3" "1"
"4" "Child 4" "1"

源代码

Xparent.java

package model;

import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Column;;

/**
 * The persistent class for the xparent database table.
 * 
 */
@Entity
@Table(schema="public", name="xparent")
@NamedQuery(name="Xparent.findAll", query="SELECT i FROM Xparent i")
public class Xparent implements Serializable
{
    private static final long serialVersionUID = -4192021332968372280L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    private Integer id;

    //bi-directional many-to-one association to Xchild
    @OneToMany(mappedBy="xparent", cascade=CascadeType.PERSIST)
    private List<Xchild> xchilds;

    @Column(length=2147483647)
    private String text;

    public Xparent() {}

    public Integer getId()
    {
        return this.id;
    }

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

    public String getText()
    {
        return text;
    }

    public void setText(String text)
    {
        this.text = text;
    }

    public List<Xchild> getXchilds()
    {
        return this.xchilds;
    }

    public void setXchilds(List<Xchild> xchilds)
    {
        this.xchilds = xchilds;
    }

    @Override
    public int hashCode() 
    {
        final int  prime   = 31;
        int        result  = 1;

        result = prime * result + ((id == null) ? 0 : id.hashCode());

        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
        {
            return true;
        }

        if (obj == null)
        {
            return false;
        }

        if (!(obj instanceof Xparent))
        {
            return false;
        }

        Xparent other = (Xparent) obj;

        if (id == null)
        {
            if (other.id != null)
            {
                return false;
            }
        }
        else if (!id.equals(other.id))
        {
            return false;
        }

        return true;
    }
}

Xchild.java

package model;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 * The persistent class for the xchild database table.
 * 
 */
@Entity
@Table(schema="public", name="xchild")
@NamedQuery(name="Xchild.findAll", query="SELECT i FROM Xchild i")
public class Xchild implements Serializable
{
    private static final long serialVersionUID = 1337852548952194022L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    private Integer id;

    @Column(length=2147483647)
    private String text;

    //bi-directional many-to-one association to Xparent
    @ManyToOne
    @JoinColumn(name="xparent_id")
    private Xparent xparent;    

    public Xchild() { }

    public Integer getId()
    {
        return this.id;
    }

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

    public String getText()
    {
        return text;
    }

    public void setText(String text)
    {
        this.text = text;
    }

    public Xparent getXparent()
    {
        return xparent;
    }

    public void setXparent(Xparent xparent)
    {
        this.xparent = xparent;
    }
}

Xcontroller.java

package controller;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.transaction.UserTransaction;
import model.Xchild;
import model.Xparent;

@Named
@RequestScoped
public class Xcontroller implements Serializable
{
    private static final long serialVersionUID = 8016446885968464239L;

    @PersistenceUnit
    private EntityManagerFactory    emf;

    @Resource
    private UserTransaction         ut;

    @Inject
    private Xparent              xparent;

    public Xparent getXparent()
    {
        return xparent;
    }

    public void setXparent(Xparent xparent)
    {
        this.xparent = xparent;
    }

    public String persist()
    {
        try
        {
            ut.begin();

            List<Xchild> xchilds = new ArrayList<Xchild>();

            for (int i = 1; i <= 4; i++)
            {
                Xchild   xchild = new Xchild();
                xchild.setText("Child " + i);                
                xchilds.add(xchild);
            }

            xparent.setText("Parent");
            xparent.setXchilds(xchilds);

            emf.createEntityManager().persist(xparent);
            ut.commit();

            System.out.println("*** Run method: " + this.getClass().getSimpleName() + ".persist() ***");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

        return "/one2ManyPersistence.xhtml";
    }
}

软件

提前致谢!

P.S。注释 @OneToMany(mappedBy="xparent") 没有保留任何记录。注释 @OneToMany(mappedBy="xparent", cascade=CascadeType.PERSIST) 保留了记录,但缺少 Xchild.xparent_id 个值。

您需要设置关系的另一端。现在您只是将子列表设置为父级,并且您需要将父级设置为每个子级。将其添加到 for 循环

xchild.setXparent(xparent);