Json 无法写入内容:未能延迟初始化角色的集合
我有一对多的关系,这是我的代码Json 无法写入内容:未能延迟初始化角色的集合,json,spring,hibernate,jackson,Json,Spring,Hibernate,Jackson,我有一对多的关系,这是我的代码 @Entity @Table(name = "catalog") public class Catalog { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "catalog_id") private int catalog_id; @NotEmpty @Size(min = 3, max = 255) @Column
@Entity
@Table(name = "catalog")
public class Catalog {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "catalog_id")
private int catalog_id;
@NotEmpty
@Size(min = 3, max = 255)
@Column(name = "name", nullable = false)
private String name;
@OneToMany(mappedBy="mycatalogorder")
private List<Order> orders;
@OneToMany(mappedBy="mycatalog")
private List<CatalogItem> items;
// setters and getters
}
@Entity
@Table(name = "catalogitem")
public class CatalogItem {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "catalogitem_id")
private int catalogitem_id;
@NotEmpty
@Size(min = 3, max = 255)
@Column(name = "name", nullable = false)
private String name;
@NotEmpty
@Column(name = "price", nullable = false)
private Double price;
@OneToOne(mappedBy="ordercatalogitem", cascade=CascadeType.ALL)
private OrderItem morderitem;
@ManyToOne
@JoinColumn(name="catalog_id", nullable=false)
private Catalog mycatalog;
// setters and getters
}
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "order_id")
private int order_id;
@NotEmpty
@Size(min = 3, max = 255)
@Column(name = "name", nullable = false)
private String name;
@NotEmpty
@Size(min = 3, max = 1024)
@Column(name = "note", nullable = false)
private String note;
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern = "ddmmYYYY HH:mm:ss")
@Column(name = "created", nullable = false)
private Date created;
@OneToMany(mappedBy="myorder")
private Set<OrderItem> orderItems;
@ManyToOne
@JoinColumn(name="catalog_id", nullable=false)
private Catalog mycatalogorder;
@PrePersist
protected void onCreate() {
created = new Date();
}
// setters and getters
}
@Entity
@Table(name = "orderitem")
public class OrderItem {
@Id
@Column(name="catalogitem_id", unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="catalogitem"))
private int catalogitem_id;
@Column(name = "quantity")
private int quantity;
@OneToOne
@PrimaryKeyJoinColumn
private CatalogItem ordercatalogitem;
@ManyToOne
@JoinColumn(name="order_id", nullable=false)
private Order myorder;
// setters and getters
}
@实体
@表(name=“catalog”)
公共类目录{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“catalog\u id”)
私有int目录id;
@空空如也
@尺寸(最小值=3,最大值=255)
@列(name=“name”,nullable=false)
私有字符串名称;
@OneToMany(mappedBy=“mycatalogorder”)
私人名单订单;
@OneToMany(mappedBy=“mycatalog”)
私人清单项目;
//二传手和接球手
}
@实体
@表(name=“catalogitem”)
公共类目录项{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“catalogitem\u id”)
私有int catalogitem_id;
@空空如也
@尺寸(最小值=3,最大值=255)
@列(name=“name”,nullable=false)
私有字符串名称;
@空空如也
@列(name=“price”,nullable=false)
私人双价;
@OneTONE(mappedBy=“ordercatalogitem”,cascade=CascadeType.ALL)
私人订单项目;
@许多酮
@JoinColumn(name=“catalog\u id”,nullable=false)
私人目录mycatalog;
//二传手和接球手
}
@实体
@表(name=“orders”)
公共阶级秩序{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“order\u id”)
私人内部订单号;
@空空如也
@尺寸(最小值=3,最大值=255)
@列(name=“name”,nullable=false)
私有字符串名称;
@空空如也
@尺寸(最小值=3,最大值=1024)
@列(name=“note”,nullable=false)
私人弦乐;
@时态(TemporalType.TIMESTAMP)
@DateTimeFormat(pattern=“ddmmYYYY HH:mm:ss”)
@列(name=“created”,nullable=false)
创建私人日期;
@OneToMany(mappedBy=“myorder”)
私人设置订单项;
@许多酮
@JoinColumn(name=“catalog\u id”,nullable=false)
私人目录mycatalogorder;
@预科生
受保护的void onCreate(){
已创建=新日期();
}
//二传手和接球手
}
@实体
@表(name=“orderitem”)
公共类OrderItem{
@身份证
@列(name=“catalogitem\u id”,unique=true,nullable=false)
@生成值(generator=“gen”)
@GenericGenerator(name=“gen”,strategy=“foreign”,parameters=@Parameter(name=“property”,value=“catalogitem”))
私有int catalogitem_id;
@列(名称=“数量”)
私人整数数量;
@奥内托内
@PrimaryKeyJoinColumn
私有目录项ordercatalogitem;
@许多酮
@JoinColumn(name=“order\u id”,null=false)
私人订单;
//二传手和接球手
}
我得到了一个例外:
org.springframework.http.converter.HttpMessageNotWritableException:
无法写入内容:未能延迟初始化内容的集合
角色:com.example.helios.model.Catalog.items,无法初始化
代理-无会话;嵌套异常是
com.fasterxml.jackson.databind.JsonMappingException:未能延迟
初始化角色的集合:
com.example.helios.model.Catalog.items无法初始化代理-
没有会议
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:271)
org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.WriteWithMessageConverterMethodProcessor(AbstractMessageConverterMethodProcessor.java:222)
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:183)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.HandlerReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
我的版本是:
- SpringFramework 4.2.4.1版本
- Hibernate 4.3.11.1最终版本
- 杰克逊2.7.4
- Jacksontype 2.7.1
- 在急切模式下加载子实体(我强烈建议您不要这样做,因为您可以加载完整的DB…,但这与您的场景有关
- 您不会使用com.fasterxml.jackson.annotation.JsonIgnore属性在JSON中序列化子实体
- 这是正常的休眠行为
在一对多关系中,hibernate加载父实体(本例中为目录),但它将以延迟模式加载子实体列表(本例中为列表项和列表顺序)
这意味着您无法访问这些对象,因为它们只是代理而不是真实对象
这非常有用,以避免在执行查询时加载完整的数据库
您有两个解决方案:
Angelo如果您不想使用渴望模式并加载所有内容,那么第三个选项很有用,就是使用Hibernate::initialize并只加载您需要的内容
Session session = sessionFactory.openSession();
Catalog catalog = (Catalog) session.load(Catalog.class, catalogId);
Hibernate.initialize(shelf);
使用FetchType.LAZY,如果仍然出现错误“无法写入内容:无法延迟初始化角色集合”,这可能是由于逻辑中的某个地方(可能是控制器中)导致的,正在尝试反序列化包含作为代理的目录项列表的目录,但事务已结束以获取该目录项。 因此,创建一个新模型(“CatalogResource”类似于catalog,但不包含项目列表)。 然后从目录中创建catalogResource对象(从查询返回)
公共类目录资源{
私有int目录id;
私有字符串名称;
私人名单订单;
}
我认为解决问题的最佳方法(也是最简单的方法)是将FetchType设置为LAZY,并使用@transient简单地注释oneToMany集合字段。
大多数情况下,将FetchType设置为EAGER不是一个好主意。
B
@OneToMany
@JoinColumn(name = "assigned_ingredient", referencedColumnName = "ingredient_id")
@Fetch(FetchMode.JOIN) // Changing the fetch profile you can solve the problem
@Where(clause = "active_ind = 'Y'")
@OrderBy(clause = "meal_id ASC")
private List<Well> ingredients;
@JsonManagedReference
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
Set<Car> cars;
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "owner_id")
private Owner owner;
@JsonIgnore
@OneToMany(mappedBy = "myorder")
private List<OrderItem> orderItems = new ArrayList<>();
@JsonProperty(value = "order_items", access = JsonProperty.Access.READ_ONLY)
private List<OrderItem> getOrderItemsList() {
if(Hibernate.isInitialized(this.relatedDictionary)){
return this.relatedDictionary;
} else{
return new ArrayList<>();
}
}
@JsonProperty(value = "order_items", access = JsonProperty.Access.WRITE_ONLY)
private void setOrderItemsList(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
for (Catalog c : allCatalogs) {
c.setItems(null);
}
objectMapper.setSerializationInclusion(Include.NON_NULL)