gpt4 book ai didi

java - Hibernate 为一对多域对象的每个创建查询插入两条记录

转载 作者:行者123 更新时间:2023-11-29 00:10:19 27 4
gpt4 key购买 nike

我有一个 Category 域对象,旨在复制分类术语树。由于一些额外的引用映射,我有必要重写对象创建代码。现在的最终结果是,Hibernate 会在每次执行 create() 时将两条数据记录插入到数据库中。一个数据记录包含所有 NULL 值,而另一个包含预期数据。

我的类别对象:

@Entity
@NamedQuery(
name="findCategoryByName",
query="select category FROM Category c WHERE c.category = :category"
)
@Table(name = "categories")
public class Category implements Serializable{

@Id
@Column(name = "category_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@Column
private String category;

@ManyToMany(mappedBy = "categories", cascade = CascadeType.PERSIST)
private List<Photo> photos= new ArrayList<>();;

@ManyToOne(cascade = CascadeType.PERSIST)
private Category parent;

@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
private List<Category> categoryList = new ArrayList<>();

public Category() { }

public Category(String category){
this.category = category;
}

/* Other getters and setters */

}

URL localhost:8080/admin/category/create 使用 POST 请求命中此 Controller 方法:

@RequestMapping(value = AdminRestURIConstants.CREATE_CATEGORY, method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Category createCategory(@RequestBody Category category){
log.info("Start creating category " + category.getCategory());
Category newCategory = categoryService.createCategory(category);
return newCategory;
}

这是我用于数据插入的存储库覆盖方法:

/**
*
* @param category
* @return
*
* A Category object can be created with two types of parent references. An Integer means the parent reference
* exists, and the new Category will be added to the existing child set. A String means the parent reference
* is non-existing, and so two Category objects are made and bound.
*
* To maintain compatibility with the field settings of the Category domain model, an Integer value is passed in as a
* String, and the execution of a parent update or create is made upon the thrown NumberFormatException when string-to-int
* conversion fails.
*/
@Override
public Category create(Category category){
try {
int parentId = Integer.parseInt(category.getParent().getCategory());

Category parent = super.findOne(parentId);
category.setParent(parent);

if (parent != null){
parent.addCategory(category);
update(parent);
}
else {
throw new NumberFormatException();
}
} catch (NumberFormatException e){

Category newParent = new Category(category.getParent().getCategory());
newParent.addCategory(newCategory);
newCategory.setParent(newParent);

super.create(newParent);
}

super.create(newCategory);
delete(category);
return newCategory;
}

截至目前,如果我传入父类别的 ID 以及一个字符串,新类别将添加到父类别 categoryList。但是,也插入了一个 NULL 记录:

{
"id": 41,
"category": "testCategory",
"photos": null,
"categoryList": [
{
"id": 42,
"category": "newCategory",
"photos": null,
"categoryList": []
},
{
"id": 83,
"category": "newCategoryChild",
"photos": null,
"categoryList": []
}
]
},
{
"id": 42,
"category": "newCategory",
"photos": null,
"categoryList": []
},
{
"id": 82,
"category": null,
"photos": null,
"categoryList": []
},
{
"id": 83,
"category": "newCategoryChild",
"photos": null,
"categoryList": []
}

如您所见,类别 newCategoryChildtestCategorycategoryList 数组中被引用。但是,在创建此记录之前,会创建一个空对象。这也在服务器日志中得到支持:

Hibernate: select category0_.category_id as category1_0_1_, category0_.category as category2_0_1_, category0_.parent_category_id as parent3_0_1_, categoryli1_.parent_category_id as parent3_0_3_, categoryli1_.category_id as category1_0_3_, categoryli1_.category_id as category1_0_0_, categoryli1_.category as category2_0_0_, categoryli1_.parent_category_id as parent3_0_0_ from categories category0_ left outer join categories categoryli1_ on category0_.category_id=categoryli1_.parent_category_id where category0_.category_id=?
Hibernate: select categoryli0_.parent_category_id as parent3_0_1_, categoryli0_.category_id as category1_0_1_, categoryli0_.category_id as category1_0_0_, categoryli0_.category as category2_0_0_, categoryli0_.parent_category_id as parent3_0_0_ from categories categoryli0_ where categoryli0_.parent_category_id=?
Hibernate: insert into categories (category, parent_category_id) values (?, ?)
Hibernate: insert into categories (category, parent_category_id) values (?, ?)

和数据库:

mysql> select * from categories;
+-------------+------------------+--------------------+
| category_id | category | parent_category_id |
+-------------+------------------+--------------------+
| 41 | testCategory | NULL |
| 42 | newCategory | 41 |
| 88 | NULL | NULL |
| 89 | newCategoryChild | 41 |
+-------------+------------------+--------------------+
4 rows in set (0.00 sec)

SO 上还有其他关于类似情况的帖子,但其中许多是未知的 mergepersist 调用的结果。我在整个数据插入过程中逐步完成了每个方法,唯一的 persistmerge 调用直接来自上面的存储库代码。

最佳答案

在您的存储库代码“public Category create(Category category){}”方法中,很明显如果 parent 为 NULL,它将抛出 new NumberFormatException(),稍后您在 catch block 中捕获异常并创建父级Category.After,您创建新的Category 对象。如你所见,你已经创建了两个对象,当parent为null时,它将创建(category NULL,parent_category_id NULL)。

需要指出的是,在你上面的方法中,没有newCategory的定义(我假设它是在你的类中声明的)并且最后一条语句“delete(category)”非常困惑。

我建议您仔细检查您的代码。

关于java - Hibernate 为一对多域对象的每个创建查询插入两条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25467490/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com