Java 使用JSONArray.fromObject将Hibernate实体转换为json

Java 使用JSONArray.fromObject将Hibernate实体转换为json,java,json,hibernate,Java,Json,Hibernate,我在将数据转换为json时遇到问题 Session session = sessionFactory.openSession(); Affiliate affiliate = (affiliate) session.get( Affiliate , pk ); session.close(); JSONArray.fromObject(affiliate); @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)

我在将数据转换为json时遇到问题

Session session = sessionFactory.openSession();       
Affiliate affiliate = (affiliate) session.get( Affiliate , pk );
session.close();
JSONArray.fromObject(affiliate);
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
显示已提取行的调试器。
但我在尝试转换为json字符串时遇到此异常:

Exception in thread "main" net.sf.json.JSONException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.affiliates.hibernate.Affiliate.employees, no session or session was closed
at net.sf.json.JSONObject._fromBean(JSONObject.java:959)    ...
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
这是我的附属实体

    @Entity(name="AFFILIATE")
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    public class Affiliate extends HibernateBean{ 

        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY) 
        @Column(name="AFFILIATE_ID")
        private long id;

        @ManyToOne(targetEntity = Affiliate.class)
        @JoinColumn(name="PARENT_ID")
        private Affiliate parent;



        @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
        @JoinTable(name="EMPLOYEES_AFFILIATES"  , joinColumns = {@JoinColumn(name="AFFILIATE_ID")},inverseJoinColumns={@JoinColumn(name="EMPLOYEE_ID")})
        private Set<Employee> employees = new HashSet<Employee>(0);

 getters and setters...

    }
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
@实体(name=“附属公司”)
@继承(策略=InheritanceType.SINGLE_表)
公共类分支扩展了HibernateBean{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“附属机构ID”)
私人长id;
@多通(targetEntity=Affiliate.class)
@JoinColumn(name=“PARENT\u ID”)
私人附属母公司;
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinTable(name=“EMPLOYEES\u AFFILIATES”,joinColumns={@JoinColumn(name=“AFFILIATE\u ID”)},inverseJoinColumns={@JoinColumn(name=“EMPLOYEES\u ID”)})
私有集employees=newhashset(0);
接球手和接球手。。。
}

谢谢

您的
员工
集合被标记为
FetchType.LAZY
,因此它是延迟获取的,在会话关闭时无法获取

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
您有几个选择:

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
  • 如果每次加载
    附属机构
    对象时都需要该集合,请将其标记为热切获取:

    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
    
  • 如果仅在这种情况下需要该集合,请指示Hibernate在这种情况下急切地加载它:

    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
    
    • 使用
      JOIN FETCH
      子句:

      @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
      
      Affiliate affiliate = (Affiliate) session.createQuery(
          "from Affiliate a join fetch a.employees where a.id = :id")
          .setParameter("id", pk).uniqueResult()
      
    • 使用
      Hibernate.initialize()

      @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
      
    • @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
      
  • 在响应准备就绪之前不要关闭会话。使用模式

  • @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
    

如果不更改数据库,则切勿更改实体。他们应该是匹配的。将实体上的fetch更改为eager会破坏延迟加载的整个想法,并且在代码中的其他地方可能会因此而引入性能问题。也就是说,如果您更改了实体,那么每个人、任何地方都必须在每次使用该实体时加载所有数据

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
您需要的是嵌套事务。在执行JSON转换的方法调用的开头启动事务,并在方法的结尾结束事务。为此,只需向包含此JSON转换的方法调用添加事务性注释

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 
完成此操作后,当需要信息时,事务不会结束,然后会发生延迟加载。很可能代码中还有其他地方可以这样做。寻找它们,并将它们作为示例,以此作为解决方案的基础

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) 

当然,如果您将在许多地方使用它,您可能需要将它下推到DAO中,以便重用

谢谢,我不明白一件事,取回懒惰意味着雇员将是空的,不是吗。。。因为如果我写的是affiliate.setEmployees(null),它工作得很好。这就是我理解的fetch lazy假设要做的,将雇员设置为null。@fatnjazzy:lazy fetching意味着
employees
是一个代理集合,当您访问它时,它会尝试获取实际的项目。
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)