[英]How do I properly delete a join instance from many-to-many in hibernate
I have three classes: PeelTestFile, DiscreteJob and PeelTestFileJob. 我有三个类:PeelTestFile,DiscreteJob和PeelTestFileJob。 This is a similar setup to the User,Group and UserGroup classic problem.
这是类似于User,Group和UserGroup经典问题的设置。 I'm trying to delete a PeelTestFileJob.
我正在尝试删除PeelTestFileJob。 When I do so, it is setting the foreign keys to null.
当我这样做时,它将外键设置为null。 This is a problem because I have the foreign keys set to NOT NULL, which is proper.
这是一个问题,因为我将外键设置为NOT NULL,这是正确的。 I want it to just remove the one record in the database, and then in Java I want it to remove the instance from the two sets to which it belongs (this is where it seems to be setting the null).
我希望它仅删除数据库中的一条记录,然后在Java中希望它从其所属的两个集合中删除该实例(这似乎是在设置null的位置)。
Below is my code. 下面是我的代码。 What's the proper way to do this?
正确的方法是什么?
public class DiscreteJob
{
private Set<PeelTestFileJob> peelTestJobs;
/**
* @hibernate.set
* inverse="true"
* lazy="true"
* cascade="all-delete-orphan"
* @hibernate.collection-key
* column="WIP_ENTITY_ID"
* @hibernate.collection-one-to-many
* class="com.icumed.ifactory3.dto.PeelTestFileJob"
*/
public Set<PeelTestFileJob> getPeelTestJobs()
{
return this.peelTestJobs;
}
public boolean remove(
PeelTestFileJob peelTestFileJob)
{
return this.peelTestJobs.remove(peelTestFileJob);
}
public void setPeelTestJobs(
Set<PeelTestFileJob> peelTestJobs)
{
this.peelTestJobs = peelTestJobs;
}
}
public class PeelTestFile
{
private Set<PeelTestFileJob> peelTestFileJobs;
/**
* @hibernate.set
* inverse="true"
* lazy="true"
* cascade="all-delete-orphan"
* @hibernate.collection-key
* column="PEEL_TEST_FILE_ID"
* @hibernate.collection-one-to-many
* class="com.icumed.ifactory3.dto.PeelTestFileJob"
*/
public Set<PeelTestFileJob> getPeelTestFileJobs()
{
return this.peelTestFileJobs;
}
public boolean remove(
PeelTestFileJob peelTestFileJob)
{
return this.peelTestFileJobs.remove(peelTestFileJob);
}
public void setPeelTestFileJobs(
Set<PeelTestFileJob> jobs)
{
this.peelTestFileJobs = jobs;
}
}
public class PeelTestFileJob
{
private PeelTestFile peelTestFile;
private DiscreteJob job;
private User createdBy;
private Date creationDate;
/**
* @hibernate.many-to-one
* column="PEEL_TEST_FILE_ID"
* not-null="true"
* outer-join="false"
*/
public PeelTestFile getPeelTestFile()
{
return this.peelTestFile;
}
public void setPeelTestFile(
PeelTestFile file)
{
this.peelTestFile = file;
}
/**
* @hibernate.many-to-one
* column="WIP_ENTITY_ID"
* not-null="true"
* outer-join="false"
*/
public DiscreteJob getJob()
{
return this.job;
}
public void setJob(
DiscreteJob job)
{
this.job = job;
}
}
Below is my code that's causing the problem: 以下是导致问题的我的代码:
super.getHibernateTemplate().delete(peelTestFileJob);
if (job.remove(peelTestFileJob)) // setting foreign key to null?
{
if (peelTestFile.remove(peelTestFileJob)) // setting foreign key to null?
{
if (peelTestFile.getPeelTestFileJobs().isEmpty())
{
// modify the peel test file here
getPeelTestFileDAO().update(peelTestFile, bioIdentification);
}
}
}
you should have 2 entity class + 1 automatically created table for many to many relationship. 您应该有2个实体类+ 1个自动创建的多对多关系表。 and the reason of why your FK data became null because you use set of your relationship table (
Set<PeelTestFileJob>
) instead of set of DiscreteJob or PeelTestFile. 以及为什么FK数据变为空的原因,是因为您使用关系表的
Set<PeelTestFileJob>
( Set<PeelTestFileJob>
)而不是DiscreteJob或PeelTestFile的集合。
entity class example to join table A many to many table B (in your case DiscreteJob with PeelTestFile): 连接表A多对多表B的实体类示例(在您的情况下为带有DiscelteFile的DiscreteJob):
in table A: 在表A中:
@ManyToMany(cascade = CascadeType.REFRESH)
@JoinTable(name="A_JOIN_B",
joinColumns={@JoinColumn(name="A_ID")},
inverseJoinColumns={@JoinColumn(name="B_ID")})
private Set<TestTableB> testJoins = new HashSet<TestTableB>();
in table B: 在表B中:
@ManyToMany(mappedBy="testJoins")
private Set<TestTableA> testJoins = new HashSet<TestTableA>();
__ _ __ _ __ _ __ _ __ _ __ _ __ _ ___ EDIT _ __ _ __ _ __ _ __ _ __ I test this and this is work : __ _ __ _ __ _ __ _ __ _ __ _ __ _ _ ____ 编辑 _ __ _ __ _ __ _ __ _ __我测试了这个,这是可行的:
the key is to use @OneToMany(mappedBy="bId", cascade = CascadeType.DETACH)
bId is FK in join table entity. 关键是使用
@OneToMany(mappedBy="bId", cascade = CascadeType.DETACH)
bId在联接表实体中为FK。 and try to delete your inverse = true if you dont need it. 并尝试删除您的inverse = true(如果不需要)。 inverse: If true, Hibernate will not try to insert or update the properties defined by this join.
反向:如果为true,则Hibernate将不会尝试插入或更新此联接定义的属性。 Default to false.
默认为false。
this is parent table example(like PeelTestFile or DiscreteJob in your case) : 这是父表示例(在您的情况下为PeelTestFile或DiscreteJob):
@Entity
@Table(name = "TEST_TABLE_B")
public class TestTableB {
//constructors here
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "B_ID")
private Long id;
@Column(name = "B_NAME")
private String bName;
@OneToMany(mappedBy="bId", cascade = CascadeType.DETACH)
private Set<AJoinB> testJoins = new HashSet<AJoinB>();
//getters and setters here
this A join B table example (in your case PeelTestFileJob): 这个A联接B表示例(在您的情况下为PeelTestFileJob):
@Entity
@Table(name = "A_JOIN_B")
public class AJoinB {
//constructors here
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
private Long id;
@Column(name = "C_NAME")
private String aName;
//you can add another column here
@Column(name = "A_ID", nullable = false)
private Long aId;
@Column(name = "B_ID", nullable = false)
private Long bId;
//getter setters here
when i do this command in java i delete 1 row in A join B table: 当我在Java中执行此命令时,我删除了A连接B表中的1行:
TestTableB b = (TestTableB) this.genericDao.getList("from TestTableB b where b.id = 1",false,null).get(0);
Set<AJoinB> testJoins = b.getTestJoins();
AJoinB ab = (AJoinB) testJoins.toArray()[0];
this.genericDao.remove(ab);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.