0

PeelTestFile、DiscreteJob、PeelTestFileJob の 3 つのクラスがあります。これは、ユーザー、グループ、およびユーザー グループの古典的な問題と同様の設定です。PeelTestFileJob を削除しようとしています。そうすると、外部キーがnullに設定されます。外部キーを NOT NULL に設定しているため、これは問題です。これは適切です。データベース内の 1 つのレコードだけを削除したいのですが、Java では、インスタンスが属する 2 つのセットからインスタンスを削除したいのです (これは、null を設定しているように見える場所です)。

以下は私のコードです。これを行う適切な方法は何ですか?

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 つの自動的に作成されたテーブルが必要です。Set<PeelTestFileJob>DiscreteJob または PeelTestFile のセットの代わりにリレーションシップ テーブルのセット ( ) を使用したために、FK データが null になった理由。

テーブル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 is FK を使用することです。必要がない場合は、 inverse = true を削除してみてください。 inverse: true の場合、Hibernate はこの結合によって定義されたプロパティを挿入または更新しようとしません。デフォルトは false です。

これは親テーブルの例です(あなたの場合は 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 に答える