未能在对象转换为json的过程中懒惰地初始化一个角色集合

我是新来的spring,同时从表中获取记录与其他表有关系得到这个懒洋洋的初始化错误。 我已经在网上阅读了很多,但没有得到适当的方法。未能在对象转换为json的过程中懒惰地初始化一个角色集合

表1:

@SuppressWarnings("serial") 

@Entity

public class Terminal extends BaseEntity {

@Column(length = 100, unique = true)

private String shortName;

@Column

private short number; // short stores up to 32767 value

@Column

private String description;

@OneToMany

@JoinColumn(name = "terminal_id", referencedColumnName = "uuid")

@Cascade({ CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DELETE })

private Set<BusinessHour> businessHour;

public String getShortName() {

return shortName;

}

public void setShortName(String shortName) {

this.shortName = shortName;

}

public short getNumber() {

return number;

}

public void setNumber(short number) {

this.number = number;

}

public String getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

public Set<BusinessHour> getBusinessHour() {

return businessHour;

}

public void setBusinessHour(Set<BusinessHour> businessHour) {

this.businessHour = businessHour;

}

表2:

@SuppressWarnings("serial") 

@Entity

public class BusinessHour extends BaseEntity {

@Column

private DayOfWeek dayOfWeek;

@Column

private LocalTime startOfOperation;

@Column

private LocalTime endOfOperation;

public DayOfWeek getDayOfWeek() {

return dayOfWeek;

}

}

服务代码:

@Service 

public class TerminalServiceImpl implements TerminalService {

@Autowired

TerminalRepository terminalRepository;

Iterable<Terminal> allTerminals = terminalRepository.findAll();

List<Terminal> terminalList = new ArrayList<Terminal>();

for (Terminal terminal : allTerminals) {

terminalList.add(terminal);

}

return terminalList;

}

终端资源库合作德:在这里我调试过程中遇到错误

@Transactional 

public interface TerminalRepository extends CrudRepository<Terminal, Long> {

}

代码:

private List<Terminal> updateTerminalList() { 

List<Terminal> allTerminals = terminalService.fetchAllTerminal();

return allTerminals;

}

public void terminalWrapperRun() {

try {

Payload payload = createTerminalPayload(applicationId);

String json3 = object2Json(payload);

kafkaRESTUtils.sendServerPayload(json3);

} catch (Exception e1) {

e1.printStackTrace();

}

}

public String object2Json(Object dataArray) throws JsonProcessingException {

return mapper.writeValueAsString(dataArray);

}

错误:

com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: terminal.model.Terminal.businessHour, could not initialize proxy - no Session (through reference chain: 

获取异常而取对象转换为JSON。我发现由于代理对象返回由于提取类型懒惰(我想保持原样)。

回答:

我相信这个问题与您的ORM默认的LAZY集合加载有关。

@OneToMany 

@JoinColumn(name = "terminal_id", referencedColumnName = "uuid")

@Cascade({ CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DELETE })

private Set<BusinessHour> businessHour;

@OneToMany注释具有fetch属性,默认情况下该属性设置为LAZY。

FetchType fetch() default LAZY; 

OneToMany reference

这意味着,当该数据被存取它只会被加载。在你的例子中,当你尝试创建JSON字符串时会发生这种情况。但是,由于这一点,你不在ORM会话的范围之内,所以它不知道如何加载数据。

因此你有2个选项。

  1. 更改您的注释到热切加载数据(这意味着BusinessHour集将在同一时间作为父对象

    @OneToMany(取= FetchType.EAGER)

  2. 被加载在ORM会话中执行你的JSON生成(我只会真正推荐这样做是导致性能问题的第一个选项)

回答:

如果我reca这正是Entity在使用时从EntityManager中分离出来的一种错误(它是一个Proxy它无法执行数据库查询来检索数据)。

您可以使用:

@OneToMany(fetch = FetchType.EAGER) 

...

private Set<BusinessHour> businessHour;

回答:

使用FetchType = EAGER意味着对你的实体的任何查询将加载一大堆注明实体的。

Imho,如果您100%确定您的实体仅用于您的特殊业务案例,这只是一个明智的行为。在所有其他情况下 - 比如将数据库编程为库,或接受对实体的不同类型的查询,您应该使用实体图(https://docs.oracle.com/javaee/7/tutorial/persistence-entitygraphs002.htm)或显式加载(Hibernate.initialize,join-fetch,请参阅示例https://vladmihalcea.com/hibernate-facts-the-importance-of-fetch-strategy/)。

如果您的使用情况下,仅是转换,你有两个很好的选择:

  • 一个事务性方法内将您的实体JSON(如PillHead建议)
  • 与所有实体明确装入实体在事务中需要(通过实体图或Hibernate.initialize),然后在需要它的地方转换为JSON。

以上是 未能在对象转换为json的过程中懒惰地初始化一个角色集合 的全部内容, 来源链接: utcz.com/qa/262982.html

回到顶部