2

重複した値が MySQL データベースに挿入されないという問題があります (Hibernate を使用)。問題は次のとおりです。親カテゴリを持つカテゴリがあります。同じ名前で親が異なる 2 つのカテゴリが存在する可能性があります (そのため、カテゴリ名を businessId として使用することはできません)。カテゴリに親がない場合 (最上位のカテゴリ)、parentId の値は NULL です。データベースに複製を挿入するために次のコードで間違っていることを理解できません。

これが私のエンティティクラスです。

@Entity
@Table(name = "category", uniqueConstraints = {@UniqueConstraint(columnNames = {"name","parentId"})})
public class Category implements Serializable {
    @Id
    @Column(name="id")
    @GeneratedValue
    private long id;

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

    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="parentId", nullable=true)
    private Category parent;

    ...
}

これは、新しいカテゴリを解析するために使用されるコードです (そして、ここで何かが間違っていると思います :-|)

 for (...) {
      Category parent = null;
      String [] categories = somePath.split("\\\\");

      for (String cat: categories) {
          Category category = new Category();
          category.setName(cat);
          category.setParent(parent);
          parent = categoryDB.insertCategory(category);
      }
 }

そして、ここにinsertCategory関数があります

public Category insertCategory (Category category) {
    Session session = sessionFactory.openSession();
    Transaction transaction = null;
    try{
        transaction = session.beginTransaction();
        category.setId((Long) session.save(category)); 
        transaction.commit();
    } catch (HibernateException e) {
        if (transaction!=null) 
            transaction.rollback();
        ...
    } finally {
        session.close(); 
    }
    return category;
}

コードを実行した後、データベースに次のエントリを取得しました。

select * from category;
+----+--------------+----------+
| id | name         | parentId |
+----+--------------+----------+
|  1 | A            |     NULL |
|  4 | A            |     NULL |
|  2 | B            |        1 |
|  3 | C            |        2 |
|  5 | B            |        4 |
|  6 | C            |        5 |
+----+--------------+----------+

「名前」だけで制限しようとすると、データベースに 3 つのエントリしか挿入されませんが、上記の状況により、名前だけで制限することはできません。

編集:この問題を解決するために私が見ていた可能性の1つは、CONSTRAINT定義での関数の使用でした(MySQLの場合はIFNULL(parentId、0)である可能性があります。そして、そのような可能性は、たとえばOracleで可能であるようです(これによるpost)、MySQL にはありません。

EDIT 2 : 実際に、MySQL バグトラッカーで同様の問題を抱えている人を見つけました。私はMySQLを使用しているので、テーブルの作成中にどのコードが生成されているかを確認しましたが、バグレポートのコードとほぼ同じでした(実際には、バグトラッカーに記載されているいくつかの基準に従ってバグではないと見なされました。とにかく、私の同僚はMS SQL Server で同等のコードを実行しようとしましたが、実際には name フィールドに同じ値を持ち、parentId が null の行を挿入できませんでした.データベース レベルで (少なくとも MySQL を使用して) 目的の CONSTRAINT を作成する可能性はないようです。それは問題の可能な回避策の1つであるため、答えを受け入れます(コードに1つの余分なクエリmagic numbersを保持することを好み、固執しません)find

どんな助けでも感謝します、ありがとう!

4

1 に答える 1