【问题标题】:JPA, @OneToMany, @ManyToOne no JoinTable, ForiegnKey never set?JPA,@OneToMany,@ManyToOne 没有加入表,外键从未设置?
【发布时间】:2014-08-19 18:11:23
【问题描述】:

我在 oneToMany 和 ManyToOne 中有以下两个类

父类:

@Entity    
class ParentBean{

@GeneratedValue( strategy = GenerationType.IDENTITY )
private Long id_parent;

@Column( name = "NAME" )    
private String name;

@OneToMany( mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER )
private List<ChildBean> revisionList;
}

子类:

@Entity    
class ChildBean {

@GeneratedValue( strategy = GenerationType.IDENTITY )
private Long id_child;
private String name;

@ManyToOne( fetch = FetchType.EAGER, cascade = CascadeType.ALL )
@JoinColumn( name = "ID_PARENT", nullable = false )
private ParentBean parent;
}

我使用以下代码来创建 bean:

ParentBean parent = new ParentBean();
parent.setName( "test parent");

List<ChildBean> revList = new ArrayList<>();

ChildBean child = new ChildBean();
child.setName( "test child" );

revList.add ( child );

parent.setRevisionList( revList );

然后我用这个将bean结构写入数据库...

@PersistenceContext
private EntityManager em;

@Override
public void addDrawing( FtDrawing drawingIn )
{

    em.persist( drawingIn );

    em.flush();
}

父 bean 已写入,但出现以下错误且子 bean 从未写入

原因: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 列“ID_PARENT”不能为空

我在网上四处查看并遵循了几个不同的示例,它们似乎都与我正在做的相同...我的数据库是 MySQL,我必须将两个主键设置为 auto_increment。最后一件事。我没有在子表中指定一个外键来关联到父表......这是必需的吗?我使用的是旧版本的休眠,没有必要......

提前感谢您的帮助

【问题讨论】:

  • 在持久化 ChildBean 之前,必须设置其 parent 字段。问题是,当您将子项添加到父项列表时,未设置子项的父字段。在持久化之前设置它(级联持久化父级时)。

标签: java jpa eclipselink one-to-many many-to-one


【解决方案1】:

要使其工作,您必须设置ChildBeanparent 字段。如果不这样做,则该字段为空,并且您的代码说它不能为空。所以你必须这样做:

ParentBean parent = new ParentBean();
parent.setName( "test parent");

List<ChildBean> revList = new ArrayList<>();

ChildBean child = new ChildBean();
child.setName( "test child" );

revList.add ( child );

child.setParent( parent ); // don't forget this.
parent.setRevisionList( revList );

为方便起见,您可以在ParentBean 中编写一个addChild 方法,它会自动执行此操作,然后您就不必担心了:

public class ParentBean {
    /* ... */

    public void addChild(ChildBean child) {
        this.revisionList.add(child);
        child.setParent(this);
    }

    /* ... */
}

然后,只需调用它而不是 parent.getRevisionList().add(child)

编辑:我认为您的代码中还有更多问题。

  • 您的ParentBeanChildBean 应该包含一个@Id 注释,您将@GeneratedValue 放在其中。
  • IMO,子表中父级的外键是必需的。我看不出有什么理由不设置它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 2017-08-31
    • 2016-09-16
    • 2016-11-14
    • 1970-01-01
    相关资源
    最近更新 更多