使用gson序列化对象并获取LazyInitializationException

时间:2014-06-11 14:17:45

标签: java spring hibernate gson

这是我的Controller方法,我试图通过提供zip,cityname和省名来读取我的数据库。

@RequestMapping(value = "/retrieve", method = RequestMethod.GET)

public @ResponseBody String retrieveObjectThroughAjax(ModelMap model){

 //Calling Service Method to read data according to zip,cityName and province provide

 PropertyItems propertyItems=getPropertyTypeandAddressService.readAddressFromZip("H2H-      
                              2N3","Montreal","Quebec");

        Gson gson = new Gson();
        String json = null;
        try{

            json = gson.toJson(propertyItems); // serializing object

        }catch(Exception e){
            logger.error(Constants.METHOD_INSIDE_MESSAGE +"getAuthors",e);

        }
        logger.debug(json);
        return json;
    }

    }

服务方法

@Service
public class GetPropertyTypeandAddressServiceImpl implements GetPropertyTypeandAddressService{

    @Autowired
    private GetPropertyTypeandAddressDAO getPropertyTypeandAddressDAO;

    @Transactional
    public PropertyItems readAddressFromZip(String zipCode,String cityName,String provinceName){
        PropertyItems propertyItems=getPropertyTypeandAddressDAO.getAddressFromZip(zipCode, cityName, provinceName);
        Hibernate.initialize(propertyItems);
        return propertyItems;

    }
}

DAO方法

@Repository
public class GetPropertyTypeandAddressDAOimp implements GetPropertyTypeandAddressDAO{
    @Autowired 
    private SessionFactory sessionFactory;

    @Override
    public PropertyItems getAddressFromZip(String zipCode,String cityName,String provinceName) {
        PropertyItems propertyitems = new PropertyItems();
          Criteria criteria = sessionFactory.getCurrentSession().createCriteria(PropertyItems.class,"propertyItemsClass");
          if(zipCode != null){
           criteria.createAlias("propertyItemsClass.address","address");
           criteria.add(Restrictions.eq("address.zip",zipCode));
          List<PropertyItems> propertyitem = criteria.list();
          if(propertyitem.size()>0){
              propertyitems  =  propertyitem.get(0);       
           }
          }
          else if(cityName != null){
               criteria.createAlias("propertyItemsClass.address","address");
               criteria.add(Restrictions.eq("address.city","city"));
               criteria.add(Restrictions.eq("city.cityname",cityName));
               List<PropertyItems> propertyitem = criteria.list();
                  if(propertyitem.size()>0){
                      propertyitems  =  propertyitem.get(0);       
                   } 
              }
          else if(provinceName != null){
              criteria.createAlias("propertyItemsClass.address","address");
               criteria.add(Restrictions.eq("address.city","city"));
               criteria.add(Restrictions.eq("city.provinces","provinces"));
               criteria.add(Restrictions.eq("provinces.provinceName",provinceName));
               List<PropertyItems> propertyitem = criteria.list();
                  if(propertyitem.size()>0){
                      propertyitems  =  propertyitem.get(0);       
                   }

              }
        return propertyitems;
    }
}

控制台错误

09:53:56,988 ERROR HelloController:567 - Inside Method: getAuthors org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.agilemaple.common.entity.Property.propertyType, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)

根据要求,我的物业项目看起来像这样

实体: 属性项目

@Entity
@Table(name="web_property_item")
public class PropertyItems {
    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    @ManyToOne
    @JoinColumn(name="property_type_id")
    private PropertyType propertyType;


    @OneToOne(mappedBy="propertyItems",cascade=CascadeType.ALL)
    private Address address;



    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public PropertyType getPropertyType() {
        return propertyType;
    }

    public void setPropertyType(PropertyType propertyType) {
        this.propertyType = propertyType;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

实体:物业类型

@Entity
@Table(name="web_property_type")
public class PropertyType {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    @ManyToOne
    @JoinColumn(name="property_id")
    private Property property;

    @OneToMany(fetch = FetchType.LAZY,mappedBy="propertyType", cascade=CascadeType.ALL)
    private Set<PropertyItems> propertyItems;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Property getProperty() {
        return property;
    }

    public void setProperty(Property property) {
        this.property = property;
    }

    public Set<PropertyItems> getPropertyItems() {
        return propertyItems;
    }

    public void setPropertyItems(Set<PropertyItems> propertyItems) {
        this.propertyItems = propertyItems;
    }

}

1 个答案:

答案 0 :(得分:0)

休眠中的问题。您的字段属性集具有Lazy fetch方法,这意味着当您调用此set的方法get时它将尝试获取。当你调用tojson方法时,gson会调用所有get对象的方法,但是此时hibernate会话已经关闭,而hibernate无法在控制器中打开它。我直接在JSP上遇到了同样的问题。在三个星期内我通过一个属性来解决hibernate(在你的情况下),我在视图拦截器中打开会话代码。我现在就在地下,所以我无法展示财产,但在一小时内我会编辑这个答案并添加财产。

添加了: 我记得 !属性是:hibernate.enable_lazy_load_no_trans = true

如果它没有帮助,我将添加opensessioninviewinterceptor的代码。

@Override
public void addInterceptors(InterceptorRegistry registry) {
    OpenSessionInViewInterceptor sessionInViewInterceptor = new OpenSessionInViewInterceptor();
    sessionInViewInterceptor.setSessionFactory(sessionFactory());
}