我在阻止将重复值插入 MySQL 数据库(使用 Hibernate)时遇到问题。问题是:我有类别,它有父类别。可以有两个名称相同但父级不同的类别(这就是类别名称不能用作 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 个整体插入到数据库中,但由于上述情况,我不能仅按名称施加限制。
编辑:我看到的解决此问题的可能性之一是 CONSTRAINT 定义中的函数使用(在 MySQL 的情况下可能是 IFNULL(parentId,0)。而且似乎这种可能性例如在 Oracle 中是可能的(根据这个发布),但不在 MySQL 中。
编辑 2:实际上我在MySQL 错误跟踪器中发现了有类似问题的人。由于我使用的是 MySQL,因此我检查了创建表时生成的代码,它几乎与 Bug 报告中的代码相同(根据 bugtracker 中提到的某些标准,它实际上认为不是错误。无论如何,我的同事有试图在 MS SQL Server 上执行等效代码,它实际上阻止了他在 name 字段和 null parentId 上插入具有相同值的行。似乎没有数据库级别的可能性(至少使用 MySQL)来制作所需的 CONSTRAINT,这很令人失望。接受答案,因为这是解决该问题的一种可能的解决方法(使用magic numbers
,我不会坚持,更喜欢find
在我的代码中保留一个额外的查询)
任何帮助将不胜感激,谢谢!