我尝试用java-hibernate-spring实现一个服务器REST,它返回一个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);
然后我有配料模型:
.....
.....
@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;
}
....
供应对象
@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
“无法写入JSON:未能懒洋洋地初始化Role:myPackage.Comprigue.Comprigue.Comprigue.Providers的集合,无法初始化代理-没有会话;嵌套异常是com.fasterxml.jackson.databind.jsonMappingException:未能懒洋洋地初始化Role:myPackage.Comprigue.Comprigue.Comprigue.Comprigue.Suppliers的集合,无法初始化代理-没有会话(通过引用链:myPackage.SupplierObject[\'配料\”]
我跟着说:
避免对未提取的惰性对象进行Jackson序列化
现在我没有这个错误,但是在返回的json中,成分字段是空的:
{
"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;
}
@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;
}
@ManyToMany(mappedBy = "ingredients")
@OrderBy("created DESC")
@BatchSize(size = 1000)
private List<Supplier> suppliers = new ArrayList<>();
@JsonIgnoreProperties(value= {"suppliers"})
public class Ingredient implements Serializable
{
......
}
无论如何,我建议您创建特定的DTO(或VO)对象,用于对JSON进行编组和解编组
我希望这是有用的
安杰洛
我在更新Spring Boot应用程序中的一个实体时得到了这个错误。 这是完整的堆栈跟踪
*非拥有实体OneToMany与mappedBy*
我得到的错误是: 键入Rapport D'异常 描述Le serveur a rencontréune erreur interne qui léa satisfaire la requute. 原因mère 注意La trace complète de La case mère de cette erreur est disponible dans les fichiers journaux d
当我试图懒洋洋地读取子实体列表时,我(断断续续地)得到了这个错误。 关于这个错误,我已经浏览了一个关于SO的帖子列表。我所能找到的就是执行EAGER fetch或使用属性。我不想做任何一个,因为他们是反模式。 我使用的是spring-data-jpa。这是一个spring-boot项目。请求来自web层(Rest控制器)
我的版本是: SpringFramework 4.2.4.发布 Hibernate4.3.11.final 杰克逊2.7.4 杰克逊类型2.7.1
我有一个应用程序(Spring 4 MVC Hibernate 4 MySQL Maven集成示例使用注释),使用基于注释的配置将Spring与Hibernate集成。 我有这个实体: 和这个: 服务中的这种方法: 在控制器中: 但我得到了这个错误: