Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate-使用生成的复合键插入临时子实体_Java_Hibernate_Jpa - Fatal编程技术网

Java Hibernate-使用生成的复合键插入临时子实体

Java Hibernate-使用生成的复合键插入临时子实体,java,hibernate,jpa,Java,Hibernate,Jpa,我在使用Hibernate插入一组临时子实体时遇到了问题,通过保存分离的父实体,这些子实体可能具有由其他临时子实体组成的复合键。我非常确定我已经正确设置了复合键类,但是每次我尝试保存具有临时实体(尚未生成ID)的父实体时,我都会遇到以下错误: org.hibernate.id.IdentifierGenerationException: null id generated for:class org._.website.data.entity.Mean 所以Hibernate从不生成复合键,我

我在使用Hibernate插入一组临时子实体时遇到了问题,通过保存分离的父实体,这些子实体可能具有由其他临时子实体组成的复合键。我非常确定我已经正确设置了复合键类,但是每次我尝试保存具有临时实体(尚未生成ID)的父实体时,我都会遇到以下错误:

org.hibernate.id.IdentifierGenerationException: null id generated for:class org._.website.data.entity.Mean
所以Hibernate从不生成复合键,我认为在给定所引用的属性的情况下,它应该能够生成复合键。但是,由于复合键引用的属性也是瞬态的,因此没有可用于手动设置复合键的ID。所以我希望Hibernate足够聪明,可以自己完成这一代

有没有办法让Hibernate使用引用其他瞬态子实体的复合键来处理瞬态子实体的保存/插入

这是我正在使用的代码。如果projectDao.save(项目)失败

如果有帮助,下面是可嵌入的MeanPK类

@Embeddable
public static class MeanPK implements Serializable {

    private static final long serialVersionUID = 341373316515655834L;

    @GeneratedValue
    @Column(name = "belief_id", nullable = false, updatable = false)
    protected Integer beliefId;

    @GeneratedValue
    @Column(name = "variable_id", nullable = false, updatable = false)
    protected Integer variableId;

    // getters/setters excluded for brevity

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof MeanPK)) {
            return false;
        }
        MeanPK other = (MeanPK) obj;
        return beliefId.equals(other.beliefId) && variableId.equals(other.variableId);
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(beliefId).append(variableId).toHashCode();
    }

}
如果必须的话,我可以先保存复合键引用的临时实体,以获取ID并手动构造MeanPK复合键,但我希望Hibernate能够通过调用projectDao.save(…)单独处理这个问题


谢谢你的帮助

研究在实体类上使用级联注释。。。保存操作将尝试在Mean具有ID之前保存项目。尝试执行projectDao.save(Mean);首先,或者对项目类上的平均集合使用级联注释

就像这样

  Mean mean = new Mean();
    mean.setVariable(variable);
    mean.setBelief(belief);
    **projectDao.save(mean);** //first option

    // I can't do this because variable and belief are transient and have no ID yet
    //MeanPK meanPk = new MeanPK(variableId, beliefId);
    //mean.setPk(meanPk);

    belief.getMeans().add(mean);

    project.getVariables().add(variable);
    project.getBeliefs().add(belief);

    projectDao.save(project);

//second option

//or in your method declaration section in your Project class remove 

getVariables().add(variable) &
getBeliefs().add(belief)

//as well as their associated variable declarations and add
// mappedBy foreign key constraint meanId
 @OneToMany(cascade = CascadeType.ALL, mappedBy = "meanId") 
//add to variable declarations section
    private Collection<Means> meansCollection;
//and add the following method under getter/setter section

    @XmlTransient
    public Collection<Mean> getMeansCollection() {
        return meansCollection;
    }

//In the Project class constructor do the following initialization of the MeanCollection

meansCollection = new ArrayList();

//now your call simply becomes 

Mean mean = new Mean();
mean.setVariable(variable);
mean.setBelief(belief);

Project project = new Project();
project.getMeansCollection().add(means);
projectDao.save(project);

// Also it looks like you should be using @JoinColumns for the variable_id &              
// belief_id fields where each variable is actually a class variable       
// representation and not an Integer. In this case you will have mean_id as   
// the single primary key and class Variable & Belief each as a @JoinColumn  
// foreign key constraint

//4 spaces
平均值=新平均值();
平均值。设置变量(变量);
挫折信念(信念);
**projectDao.save(平均值);**//第一购股权
//我不能这样做,因为变量和信念是暂时的,还没有ID
//MeanPK MeanPK=新的MeanPK(variableId,beliefId);
//平均setPk(平均PK);
belience.getMeans().add(mean);
project.getVariables().add(变量);
project.getbelies().add(信念);
projectDao.save(project);
//第二种选择
//或者在项目类的方法声明部分删除
getVariables().add(变量)&
getbelies().add(信念)
//以及它们关联的变量声明和添加
//mappedBy外键约束meanId
@OneToMany(cascade=CascadeType.ALL,mappedBy=“meanId”)
//添加到变量声明部分
私人收藏是指收藏;
//并在getter/setter部分下添加以下方法
@XmlTransient
公共集合getMeansCollection(){
返回均值集合;
}
//在项目类构造函数中,对集合进行以下初始化
meansCollection=new ArrayList();
//现在你的电话变得简单了
平均值=新平均值();
平均值。设置变量(变量);
挫折信念(信念);
项目=新项目();
project.getMeansCollection().add(means);
projectDao.save(project);
//另外,看起来您应该使用@JoinColumns作为变量_id&
//信念id字段,其中每个变量实际上是一个类变量
//表示,而不是整数。在这种情况下,您的平均id为
//单个主键和类变量&confidence都作为@JoinColumn
//外键约束
//4个空间

我找到了问题的答案,我想我会把它贴出来,以防有人发现它有用

我所做的是将引用变量和信念实体设置为Mean实体时,将它们存储在MeanPK类本身中。我向MeanPk类中的ID获取程序添加了一些逻辑,这样当hibernate调用它们时,它将首先检查设置MeanPk类中存储的对象的ID。这是因为hibernate将在到达平均实体之前插入并持久化瞬态变量和信念实体,因为它是最底层的子实体。我的所有集合都有CascadeType.ALL,因此我不需要担心手动保存每个实体,Hibernate将把保存操作从父级级联到子级

以下是更新后的MeanPK类和Mean实体类:

@Entity
@Table(name = "mean")
public class Mean implements Serializable {

    private static final long serialVersionUID = -5732898358425089380L;


    // composite key
    @EmbeddedId
    private MeanPK pk = new MeanPK();

    @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
    @JoinColumn(name = "belief_id", insertable = false, nullable = false, updatable = false)
    private Belief belief;

    @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
    @JoinColumn(name = "variable_id", insertable = false, nullable = false, updatable = false)
    private Variable variable;

    // more attributes excluded

    public MeanPK getPk() {
        return pk;
    }

    protected void setPk(MeanPK pk) {
        this.pk = pk;
    }


    public Belief getBelief() {
        return belief;
    }

    public void setBelief(Belief belief) {
        pk.setBelief(this.belief = belief);
    }


    @XmlTransient
    public Variable getVariable() {
        return variable;
    }

    public void setVariable(Variable variable) {
        pk.setVariable(this.variable = variable);
    }


    @Embeddable
    public static class MeanPK implements Serializable {

        private static final long serialVersionUID = 341373316515655834L;

        @Access(AccessType.PROPERTY)
        @Column(name = "belief_id", nullable = false, updatable = false)
        protected Integer beliefId;

        @Access(AccessType.PROPERTY)
        @Column(name = "variable_id", nullable = false, updatable = false)
        protected Integer variableId;

        @Transient
        private Belief belief;

        @Transient
        private Variable variable;


        public Integer getBeliefId() {
            if (beliefId == null && belief != null) {
                beliefId = belief.getId();
            }
            return beliefId;
        }

        protected void setBeliefId(Integer beliefId) {
            this.beliefId = beliefId;
        }

        public Belief getBelief() {
            return belief;
        }

        void setBelief(Belief belief) {
            this.belief = belief;
            if (belief != null) {
                beliefId = belief.getId();
            }
        }


        public Integer getVariableId() {
            if (variableId == null && variable != null) {
                variableId = variable.getId();
            }
            return variableId;
        }

        protected void setVariableId(Integer variableId) {
            this.variableId = variableId;
        }

        public Variable getVariable() {
            return variable;
        }

        void setVariable(Variable variable) {
            this.variable = variable;
            if (variable != null) {
                variableId = variable.getId();
            }
        }


        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (!(obj instanceof MeanPK)) {
                return false;
            }
            MeanPK other = (MeanPK) obj;
            return getBeliefId().equals(other.getBeliefId()) && getVariableId().equals(other.getVariableId());
        }

        @Override
        public int hashCode() {
            return new HashCodeBuilder().append(getBeliefId()).append(getVariableId()).toHashCode();
        }

    }

}
是的,这是暂时的

那么你是这样打电话的

MeanPK MeanPK=新的MeanPK(variableId,beliefId)

打这个电话时这对你有用吗


平均值=新平均值(变量ID,beliefId)

欢迎来到堆栈溢出!谢谢你的回答,但请让它更具解释性,最好是显示OP在哪里进行更改。
@Entity
@Table(name = "mean")
public class Mean implements Serializable {

    private static final long serialVersionUID = -5732898358425089380L;


    // composite key
    @EmbeddedId
    private MeanPK pk = new MeanPK();

    @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
    @JoinColumn(name = "belief_id", insertable = false, nullable = false, updatable = false)
    private Belief belief;

    @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
    @JoinColumn(name = "variable_id", insertable = false, nullable = false, updatable = false)
    private Variable variable;

    // more attributes excluded

    public MeanPK getPk() {
        return pk;
    }

    protected void setPk(MeanPK pk) {
        this.pk = pk;
    }


    public Belief getBelief() {
        return belief;
    }

    public void setBelief(Belief belief) {
        pk.setBelief(this.belief = belief);
    }


    @XmlTransient
    public Variable getVariable() {
        return variable;
    }

    public void setVariable(Variable variable) {
        pk.setVariable(this.variable = variable);
    }


    @Embeddable
    public static class MeanPK implements Serializable {

        private static final long serialVersionUID = 341373316515655834L;

        @Access(AccessType.PROPERTY)
        @Column(name = "belief_id", nullable = false, updatable = false)
        protected Integer beliefId;

        @Access(AccessType.PROPERTY)
        @Column(name = "variable_id", nullable = false, updatable = false)
        protected Integer variableId;

        @Transient
        private Belief belief;

        @Transient
        private Variable variable;


        public Integer getBeliefId() {
            if (beliefId == null && belief != null) {
                beliefId = belief.getId();
            }
            return beliefId;
        }

        protected void setBeliefId(Integer beliefId) {
            this.beliefId = beliefId;
        }

        public Belief getBelief() {
            return belief;
        }

        void setBelief(Belief belief) {
            this.belief = belief;
            if (belief != null) {
                beliefId = belief.getId();
            }
        }


        public Integer getVariableId() {
            if (variableId == null && variable != null) {
                variableId = variable.getId();
            }
            return variableId;
        }

        protected void setVariableId(Integer variableId) {
            this.variableId = variableId;
        }

        public Variable getVariable() {
            return variable;
        }

        void setVariable(Variable variable) {
            this.variable = variable;
            if (variable != null) {
                variableId = variable.getId();
            }
        }


        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (!(obj instanceof MeanPK)) {
                return false;
            }
            MeanPK other = (MeanPK) obj;
            return getBeliefId().equals(other.getBeliefId()) && getVariableId().equals(other.getVariableId());
        }

        @Override
        public int hashCode() {
            return new HashCodeBuilder().append(getBeliefId()).append(getVariableId()).toHashCode();
        }

    }

}