0

我有三个类:PeelTestFile、DiscreteJob 和 PeelTestFileJob。这与 User、Group 和 UserGroup 经典问题的设置类似。我正在尝试删除 PeelTestFileJob。当我这样做时,它将外键设置为空。这是一个问题,因为我将外键设置为 NOT NULL,这是正确的。我希望它只删除数据库中的一条记录,然后在 Java 中我希望它从它所属的两组中删除实例(这似乎是设置空值的地方)。

下面是我的代码。这样做的正确方法是什么?

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;
  }
}

以下是导致问题的我的代码:

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);
    }
  }
}
4

1 回答 1

0

您应该有 2 个实体类 + 1 个自动创建的多对多关系表。以及为什么您的 FK 数据变为空的原因是因为您使用了一组关系表 ( Set<PeelTestFileJob>) 而不是一组 DiscreteJob 或 PeelTestFile。

连接表 A 多对多表 B 的实体类示例(在您的情况下为带有 PeelTestFile 的 DiscreteJob):

在表 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>();

在表 B 中:

@ManyToMany(mappedBy="testJoins")
private Set<TestTableA> testJoins = new HashSet<TestTableA>();

__ _ __ _ __ _ __ _ __ _ __ _ __ _ ___编辑_ __ _ __ _ __ _ __ _ __ 我对此进行了测试,这是工作:

关键是在连接表实体中使用@OneToMany(mappedBy="bId", cascade = CascadeType.DETACH)bId 是 FK。如果不需要,请尝试删除您的 inverse = true 。 inverse:如果为 true,Hibernate 将不会尝试插入或更新此连接定义的属性。默认为假。

这是父表示例(如您的情况下的 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

这个 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

当我在 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);
于 2013-07-20T08:06:50.397 回答