java – 无法编写JSON:无法懒惰地初始化角色集合
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 无法编写JSON:无法懒惰地初始化角色集合,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5362字,纯文字阅读大概需要8分钟。
内容图文
![java – 无法编写JSON:无法懒惰地初始化角色集合](/upload/InfoBanner/zyjiaocheng/806/4b1b6b42328c46a59095684029ad6fc6.jpg)
我正在实现一个服务器REST与java – hibernate – spring,它返回一个json
我有很多关系的地图.
我解释得更好,我有一个供应商,有一份成分清单,每个成分都有供应商清单.
我创建了表格:
CREATE TABLE supplier_ingredient (
supplier_id BIGINT,
ingredient_id BIGINT
)
ALTER TABLE supplier_ingredient ADD CONSTRAINT supplier_ingredient_pkey
PRIMARY KEY(supplier_id, ingredient_id);
ALTER TABLE supplier_ingredient ADD CONSTRAINT
fk_supplier_ingredient_ingredient_id FOREIGN KEY (ingredient_id)
REFERENCES ingredient(id);
ALTER TABLE supplier_ingredient ADD CONSTRAINT
fk_supplier_ingredient_supplier_id FOREIGN KEY (supplier_id) REFERENCES
supplier(id);
然后我有Ingredient模型:
.....
.....
@ManyToMany(mappedBy = "ingredients")
@OrderBy("created DESC")
@BatchSize(size = 1000)
private List<Supplier> suppliers = new ArrayList<>();
....
....
然后我有供应商型号:
....
@ManyToMany
@JoinTable( name = "supplier_ingredient ",
joinColumns = @JoinColumn(name = "supplier_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "ingredient_id", referencedColumnName = "id"),
foreignKey = @ForeignKey(name = "fk_supplier_ingredient_supplier_id"))
@OrderBy("created DESC")
@Cascade(CascadeType.SAVE_UPDATE)
@BatchSize(size = 1000)
private List<Ingredient> ingredients = new ArrayList<>();
....
终点:
@RequestMapping(value = "/{supplierId:[0-9]+}", method = RequestMethod.GET)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
public SupplierObject get(@PathVariable Long supplierId) {
Supplier supplier = supplierService.get(supplierId);
SupplierObject supplierObject = new SupplierObject (supplier);
return SupplierObject;
}
服务
....
public Supplier get(Long supplierId) {
Supplier supplier = supplierDao.getById(supplierId); (it does entityManager.find(entityClass, id))
if (supplier == null) throw new ResourceNotFound("supplier", supplierId);
return supplier;
}
....
SupplierObject
@JsonIgnoreProperties(ignoreUnknown = true)
public class SupplierObject extends IdAbstractObject {
public String email;
public String phoneNumber;
public String address;
public String responsible;
public String companyName;
public String vat;
public List<Ingredient> ingredients = new ArrayList<>();
public SupplierObject () {
}
public SupplierObject (Supplier supplier) {
id = supplier.getId();
email = supplier.getEmail();
responsible = supplier.getResponsible();
companyName = supplier.getCompanyName();
phoneNumber = supplier.getPhone_number();
ingredients = supplier.getIngredients();
vat = supplier.getVat();
address = supplier.getAddress();
}
}
和IdAbstractObject
public abstract class IdAbstractObject{
public Long id;
}
我的问题是,当我调用端点时:
http://localhost:8080/supplier/1
我收到一个错误:
“Could not write JSON: failed to lazily initialize a collection of
role: myPackage.ingredient.Ingredient.suppliers, could not initialize
proxy – no Session; nested exception is
com.fasterxml.jackson.databind.JsonMappingException: failed to lazily
initialize a collection of role:
myPackage.ingredient.Ingredient.suppliers, could not initialize proxy
– no Session (through reference chain: myPackage.supplier.SupplierObject[\”ingredients\”]->org.hibernate.collection.internal.PersistentBag[0]->myPackage.ingredient.Ingredient[\”suppliers\”])”
我错了什么?
@Nikhil Yekhe
我跟着这个:
Avoid Jackson serialization on non fetched lazy objects
现在我没有错误,但在json返回时,ingredients字段为null:
{
"id": 1,
"email": "mail@gmail.com",
"phoneNumber": null,
"address": null,
"responsible": null,
"companyName": "Company name",
"vat": "vat number",
"ingredients": null
}
但在调试中我可以看到成分….
解决方法:
这是Hibernate和Jackson Marshaller的正常行为
基本上您希望拥有以下内容:包含所有供应商对象详细信息的JSON …包括成分.
请注意,在这种情况下,您必须非常小心,因为当您尝试创建JSON本身时可以有一个循环引用,因此您还应该使用JsonIgnore注释
您必须做的第一件事是加载供应商及其所有细节(包括成分).
你怎么能这样做?通过使用几个策略…让我们使用Hibernate.initialize.这必须在关闭DAO(或存储库)实现中的hibernate会话之前使用(基本上在你使用hibernate会话的地方).
所以在这种情况下(我假设使用Hibernate)在我的存储库类中,我应该写这样的东西:
public Supplier findByKey(Long id)
{
Supplier result = (Supplier) getSession().find(Supplier.class, id);
Hibernate.initialize(result.getIngredients());
return result;
}
现在您拥有Supplier对象及其所有细节(成分也是如此)
现在,在您的服务中,您可以做您所做的事情:
@RequestMapping(value = "/{supplierId:[0-9]+}", method = RequestMethod.GET)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
public SupplierObject get(@PathVariable Long supplierId)
{
Supplier supplier = supplierService.get(supplierId);
SupplierObject supplierObject = new SupplierObject (supplier);
return SupplierObject;
}
通过这种方式Jackson可以编写JSON,但让我们看一下Ingredient对象..它具有以下属性:
@ManyToMany(mappedBy = "ingredients")
@OrderBy("created DESC")
@BatchSize(size = 1000)
private List<Supplier> suppliers = new ArrayList<>();
杰克逊试图创建JSON时会发生什么?它将访问List< Ingredient>内的每个元素.它也会尝试为这个创建一个JSON ….也是供应商列表,这是一个循环引用…所以你必须避免它,你可以通过使用JsonIgnore注释来避免它.例如,您可以用这种方式编写您的Ingredient实体类:
@JsonIgnoreProperties(value= {"suppliers"})
public class Ingredient implements Serializable
{
......
}
这样你:
>使用所有相关成分加载供应商对象
>当您尝试创建JSON本身时,请避免使用循环引用
在任何情况下,我都建议您创建特定的DTO(或VO)对象,用于编组和解组JSON
我希望这很有用
安杰洛
内容总结
以上是互联网集市为您收集整理的java – 无法编写JSON:无法懒惰地初始化角色集合全部内容,希望文章能够帮你解决java – 无法编写JSON:无法懒惰地初始化角色集合所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。