懒惰的获取元素

时间:2017-10-06 18:24:29

标签: spring hibernate

我使用连接提取查询来获取公司以及productSLA,因为公司有用户列表并且它没有被初始化。因此,当我使用responseentity.ok发送响应时,它会抛出延迟初始化异常。我不想要用于此目的的用户列表是否有任何方式我可以将其发送到前端而不会得到懒惰的初始化异常,有人建议我使用dto执行此操作。

我在前端使用棱角分明。当我使用jsp时,我从未遇到过这种问题。

@Entity
@Table(name = "USER_TABLE")
public class User {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Integer userId;

 @OneToMany(mappedBy = "user", cascade = CascadeType.ALL,fetch=FetchType.EAGER)
 private List<Ticket> raisedTickets;

 @NotNull
 @Column(unique = true)
 @Email(message = "Invalid Email")
 private String email;

 @NotNull
 @Column
 @Length(min = 4, max = 12, message = "First name must be between 4 to 12 character long")
 private String firstName;

 @NotNull
 @Column
 @Length(min = 4, max = 12, message = "Last name must be between 4 to 12 character long")
 private String lastName;

 @NotNull
 @Column
 @Length(min = 8, max = 100, message = "Password must be 4 to 12 character long")
 private String password;

 @NotNull
 @Column
 @Length(min = 3, max = 30, message = "Company Name must be between 3 to 12 character long")
 private String companyName;

 @Column(name = "USER_ROLE")
 @Enumerated(EnumType.STRING)
 private UserRolesEnum userRole;

 @ManyToOne
 @JoinColumn(name = "COMPANY_ID", nullable = false)
 @NotNull
 private Company company;

 @OneToMany(mappedBy="user", cascade=CascadeType.ALL)
 private List<ProductAssociated> productAssociatedList=new ArrayList<ProductAssociated>();

 public User() {
 }

 public User(String firstName, String lastName, String email, String password, String companyName,
   UserRolesEnum role) {
  super();
  this.firstName = firstName;
  this.lastName = lastName;
  this.email = email;
  this.password = password;
  this.companyName = companyName;
  this.userRole = role;
 }

 public Integer getUserId() {
  return userId;
 }

 public void setUserId(Integer id) {
  this.userId = id;
 }

 public List<Ticket> getRaisedTickets() {
  return raisedTickets;
 }
 public void setRaisedTickets(List<Ticket> raisedTickets) {
  this.raisedTickets = raisedTickets;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getEmail() {
  return email;
 }

 public void setEmail(String email) {
  this.email = email;
 }

 public String getPassword() {
  return password;
 }

 public void setPassword(String password) {
  this.password = password;
 }

 public String getCompanyName() {
  return companyName;
 }

 public void setCompanyName(String companyName) {
  this.companyName = companyName;
 }

 public UserRolesEnum getUserRole() {
  return userRole;
 }

 public void setUserRole(UserRolesEnum userRole) {
  this.userRole = userRole;
 }

 public Company getCompany() {
  return company;
 }

 public void setCompany(Company company) {
  this.company = company;
 }

 public List<ProductAssociated> getProductAssociatedList() {
  return productAssociatedList;
 }

 public void setProductAssociatedList(List<ProductAssociated> productAssociatedList) {
  this.productAssociatedList = productAssociatedList;
 }

 public void addProductAssociated(ProductAssociated productAssociated) {
  productAssociatedList.add(productAssociated);
  productAssociated.setUser(this);
}  





    @Entity
@Table(name="PRODUCT_SLA")
public class ProductSLA {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 @Column(name="SLA_ID")
 private Integer slaId;

 @NotNull
 @Column(name="RESPONSE_TIME")
 private int responseTime;

 @Column(name="RESOLVE_TIME")
 private int resolveTime;

 @NotNull
 @Column(name="PRIORITY")
 @Enumerated(EnumType.STRING)
 private PriorityEnum priority;

 @ManyToOne
 @JoinColumn(name="COMPANY_ID", nullable = false)
 private Company company;

 @ManyToOne
 @JoinColumn(name="PRODUCT_ID", nullable = false)
 private Product product;

 public ProductSLA() {
  super();
 }

 public ProductSLA(Integer slaId, int responseTime, int resolveTime, PriorityEnum priority) {
  super();
  this.slaId = slaId;
  this.responseTime = responseTime;
  this.resolveTime = resolveTime;
  this.priority = priority;
 }

 public Integer getSlaId() {
  return slaId;
 }

 public void setSlaId(Integer slaId) {
  this.slaId = slaId;
 }

 public int getResponseTime() {
  return responseTime;
 }

 public void setResponseTime(int responseTime) {
  this.responseTime = responseTime;
 }

 public int getResolveTime() {
  return resolveTime;
 }

 public void setResolveTime(int resolveTime) {
  this.resolveTime = resolveTime;
 }

 public PriorityEnum getPriority() {
  return priority;
 }

 public void setPriority(PriorityEnum priority) {
  this.priority = priority;
 }

 public Company getCompany() {
  return company;
 }

 public void setCompany(Company company) {
  this.company = company;
 }

 public Product getProduct() {
  return product;
 }

 public void setProduct(Product product) {
  this.product = product;
 }

}



    @Entity
@Table(name = "COMPANY_TABLE")
public class Company {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "COMPANY_ID")
 private Integer companyId;

 @NotNull
 @Column(name = "COMPANY_NAME", unique = true)
 private String companyName;

 @NotNull
 @Column(name = "ADDRESS_LINE1")
 private String addressLine1;

 @Column(name = "ADDRESS_LINE2")
 private String addressLine2;

 @NotNull
 @Column(name = "CITY")
 private String city;

 @NotNull

 @Column(name="STATE_NAME")

 private String state;

 @NotNull
 @Column(name = "COUNTRY")
 private String country;

 @NotNull
 @Column(name = "PHONE")
 private String phone;

 @NotNull
 @Column(name = "POSTAL_CODE")
 private String postalCode;

 @NotNull
 @Column(name = "COMPANY_WEBSITE")
 private String companyWebsite;

 @OneToMany( mappedBy = "company", cascade = CascadeType.ALL)
 private List<User> userList = new ArrayList<User>();

 @OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
 private List<ProductSLA> productSLAList = new ArrayList<ProductSLA>();

 @OneToMany(mappedBy = "company", cascade = CascadeType.ALL, orphanRemoval=true)
 private List<AccessLevel> accessLevelList=new ArrayList<AccessLevel>();

 public Company() {
  super();
 }

 public Company(Integer companyId, String companyName, String addressLine1, String addressLine2, String city,
   String state, String country, String phone, String postalCode, String companyWebsite) {
  super();
  this.companyId = companyId;
  this.companyName = companyName;
  this.addressLine1 = addressLine1;
  this.addressLine2 = addressLine2;
  this.city = city;
  this.state = state;
  this.country = country;
  this.phone = phone;
  this.postalCode = postalCode;
  this.companyWebsite = companyWebsite;
 }

 public Integer getCompanyId() {
  return companyId;
 }

 public void setCompanyId(Integer companyId) {
  this.companyId = companyId;
 }

 public String getCompanyName() {
  return companyName;
 }

 public void setCompanyName(String companyName) {
  this.companyName = companyName;
 }

 public String getAddressLine1() {
  return addressLine1;
 }

 public void setAddressLine1(String addressLine1) {
  this.addressLine1 = addressLine1;
 }

 public String getAddressLine2() {
  return addressLine2;
 }

 public void setAddressLine2(String addressLine2) {
  this.addressLine2 = addressLine2;
 }

 public String getCity() {
  return city;
 }

 public void setCity(String city) {
  this.city = city;
 }

 public String getState() {
  return state;
 }

 public void setState(String state) {
  this.state = state;
 }

 public String getCountry() {
  return country;
 }

 public void setCountry(String country) {
  this.country = country;
 }

 public String getPhone() {
  return phone;
 }

 public void setPhone(String phone) {
  this.phone = phone;
 }

 public String getPostalCode() {
  return postalCode;
 }

 public void setPostalCode(String postalCode) {
  this.postalCode = postalCode;
 }

 public String getCompanyWebsite() {
  return companyWebsite;
 }

 public void setCompanyWebsite(String companyWebsite) {
  this.companyWebsite = companyWebsite;
 }

 public List<User> getUserList() {
  return userList;
 }

 public void setUserList(List<User> userList) {
  this.userList = userList;
 }

 public void addUser(User user) {
  userList.add(user);
  user.setCompany(this);
 }

 public List<ProductSLA> getProductSLAList() {
  return productSLAList;
 }

 public void setProductSLAList(List<ProductSLA> productSLAList) {
  this.productSLAList = productSLAList;
 }

 public void addProductSLA(ProductSLA productSLA) {
  productSLAList.add(productSLA);
  productSLA.setCompany(this);
 }


 public List<AccessLevel> getAccessLevelList() {
  return accessLevelList;
 }

 public void setAccessLevelList(List<AccessLevel> accessLevelList) {
  this.accessLevelList = accessLevelList;
 }

 public void addAccessLevel(AccessLevel accessLevel) {
  accessLevelList.add(accessLevel);
  accessLevel.setCompany(this);
 }
}

编辑 我找到了解决方案,但我很困惑使用哪个以及如何使用,因为那里有很多解决方案。 Avoid Jackson serialization on non fetched lazy objects

2 个答案:

答案 0 :(得分:0)

假设你的hibernate会话已经在控制器中关闭了(这是一个公平的假设,因为我们不想在spring / hibernate层之外公开我们的hibernate会话)如果你试图你会遇到这种类型的问题访问在会话中未加载的集合。

好的!

我还假设您正在返回一个或一组“休眠管理实体”而不是DTO。我所感知的是,当该实体转换为JSON时,所有的getter都被底层框架调用,除非它们被标记为'ignore'(或类似的东西)。或者可能是您的UI正在调用userList,因为hibernate返回了代理,因此它会抛出异常。

无论如何,最好还是按照自己喜欢的方式返回DTO并填充它。返回DTO(或DTO集合)比返回实体更受欢迎有多种原因。

答案 1 :(得分:0)

要解决此问题,我使用了http消息转换器

应用程序配置如下所示:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(jacksonMessageConverter());
    super.configureMessageConverters(converters);
}

public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new Hibernate5Module());
    messageConverter.setObjectMapper(mapper);
    return messageConverter;

}

需要依赖

<dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-hibernate5</artifactId>
        <version>2.8.7</version>
    </dependency>

如果您愿意修改每个getter,还有一个脏的解决方案: jackson 2 object to json ignore lazy loading