用Jackson注释映射hibernate实体 [英] Mapping hibernate entity with Jackson annotation

查看:191
本文介绍了用Jackson注释映射hibernate实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring,hibernate和MySql,但我在查询结果分散化方面遇到了一些问题。
首先在我的实体中,我在Set结构(@OneToMany方)和@JsonBackReference上添加了@JsonManagedReference(@ManyToOne方),它工作正常,但我无法检索所有需要的信息(例如@ManyToOne参考)。
所以我交换@JsonBackReference对set结构和@JsonManagedReference在单个对象上,但我检索

 找不到类的序列化程序org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer并没有发现创建BeanSerializer的属性(以避免异常,禁用SerializationFeature.FAIL_ON_EMPTY_BEANS))(通过引用链:com.model.tablesField.TableUI [data]  - > java .util.ArrayList [0]  - > com.domain.Car [carType]  - > com.domain.CarType _ $$ _ jvst744_f [handler])
pre>

我也尝试过使用Set结构的@JsonIgnore,但它不适用于相同的问题。
这是我的spring配置

  private属性getHibernateProperties(){
Properties properties = new Properties() ;
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT,env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
// properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL,env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL,env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
properties.put(hibernate.enable_lazy_load_no_trans,true);
返回属性;

这是我几个实体中的一个:

  / ** 
*由hbm2java生成的车
* /
@Entity
@Table(name =car ,catalog =ATS)
public class Car实现java.io.Serializable {
$ b $ / **
*
* /
private static final long serialVersionUID = 1L;
私人整数idCar;
@JsonManagedReference
私人CarType carType;
@JsonManagedReference
私人舰队舰队;
私人字符串ID;
private int initialKm;
私人字符串carChassis;
私人字符串笔记;
@JsonBackReference
私人设置< Acquisition> acquisitions = new HashSet< Acquisition>(0);

公共汽车(){
}

公共汽车(CarType carType,Fleet fleet,int initialKm,String carChassis){
this.carType = carType;
this.fleet =舰队;
this.initialKm = initialKm;
this.carChassis = carChassis;

$ b $ public Car(CarType carType,Fleet fleet,String id,int initialKm,String carChassis,String note,
Set< Acquisition> acquisitions){
this .carType = carType;
this.fleet =舰队;
this.id = id;
this.initialKm = initialKm;
this.carChassis = carChassis;
this.note = note;
this.acquisitions =收购;


@Id
@GeneratedValue(strategy = IDENTITY)

@Column(name =id_car,unique = true,nullable = false )
public Integer getIdCar(){
return this.idCar;
}

public void setIdCar(Integer idCar){
this.idCar = idCar;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =id_carType,nullable = false)
public CarType getCarType(){
返回this.carType;
}

public void setCarType(CarType carType){
this.carType = carType;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =id_fleet,nullable = false)
public Fleet getFleet(){
返回this.fleet;
}

public void setFleet(Fleet fleet){
this.fleet = fleet;

$ b $ @Column(name =id,length = 5)
public String getId(){
return this.id;
}

public void setId(String id){
this.id = id;


@Column(name =initialKm,nullable = false)
public int getInitialKm(){
return this.initialKm;
}

public void setInitialKm(int initialKm){
this.initialKm = initialKm;


@Column(name =carChassis,nullable = false,length = 20)
public String getCarChassis(){
return this.carChassis;
}

public void setCarChassis(String carChassis){
this.carChassis = carChassis;


@Column(name =note,length = 100)
public String getNote(){
return this.note;
}

public void setNote(String note){
this.note = note;
}

@OneToMany(fetch = FetchType.LAZY,mappedBy =car)
public Set< Acquisition> getAcquisitions(){
返回this.acquisitions;


public void setAcquisitions(Set< Acquisition> acquisitions){
this.acquisitions = acquisitions;
}

}

一种使用查询的方法:

  @Override 
@RequestMapping(value = {/ cars / {idFleet}},method = RequestMethod。 GET)
public @ResponseBody TableUI getCars(@PathVariable int idFleet){
TableUI ajaxCall = new TableUI();
try {
ajaxCall.setData(fleetAndCarService.findCarsByIdFleet(idFleet));
返回ajaxCall;
} catch(QueryException e){
ErrorResponse errorResponse = ErrorResponseBuilder.buildErrorResponse(e);
LOG.error(在FleetAndCarControllerImpl :: addCar中抛出异常:+ errorResponse.getStacktrace());
返回ajaxCall;


查询的两个类:

  public interface DefRdiRepository扩展JpaRepository< DefRdi,Integer> {


// @ Query(SELECT CASE WHEN COUNT(c)> 0 THEN ELSE false END FROM DEFRDI c WHERE c.parName =?1 AND c.description =?2)
// Boolean existsByParNameAndDescription(String parName,String description);
//查询spring的方法,我把findBy和研究的关键字
DefRdi findByParNameAndDescription(String parName,String description);
}

public interface CarRepository扩展JpaRepository< Car,Integer>,CarRepositoryCustom {

// Spring的查询方法,我把findBy和研究的关键
列表< Car> findByFleetIdFleet(int idFleet);

}

我的错误在哪里?我不想Set对象,但只有单个引用。问题是只有当我序列化。谢谢

更新
我在所有集合collectionts和Eager上使用@JSonIgnore,而不是懒惰广告,所有工作正常,只有当我想要时才能检索所有信息,例如有两个不同的查询?
因此它不起作用

$ $ p $ $ $ $ c $ @Override
@Transactional
public List< Car> ; findByFleetIdFleet(int idFleet){
List< Car> carList = carRepository.findByFleetIdFleet(idFleet); (Car car:carList)

Hibernate.initialize(car.getCarType());
Hibernate.initialize(car.getFleet());
}
返回carList;
//返回carRepository.findByFleetIdFleet(idFleet);


解决方案

所有集合都需要提取当从数据库中加载它们以便被Spring序列化时,他们急切地想要。确保您热切地获取它们(例如FetchMode.JOIN)。您还可以使用@JsonIgnore将@JsonManagedReference从需要的字段中交换到黑色列出的字段中,Spring会自动将每个字段串行化,而无需注释。
$ b 更新



将数据存储库更改为类似的东西应该可行,但我不确定它是否编译,但我认为您会明白的:

  @EntityGraph(value =some.entity.graph,type = EntityGraph.EntityGraphType.FETCH)
@Query(
value = SELECT c FROM Car c INNER JOIN FETCH c.acquisitions WHERE c.id =:idFleet

public interface CarRepository扩展JpaRepository< Car,Integer> ;, CarRepositoryCustom {

/ / spring的查询方法,我把findBy再研究一下key
List< Car> findByFleetIdFleet(int idFleet);

$ b $ / code>

欲了解更多信息,请查看发布并阅读官方文档



解决方法:

似乎有一个解决方法,但是获取这些集合像上面所显示的渴望应该会对性能产生积极的影响,因为之后不需要加载代理。在控制器级别也不需要打开事务。

I'm working with Spring, hibernate and MySql but I have some problem with seralization of query result. First in my entity I added @JsonManagedReference on Set structure (@OneToMany side) and @JsonBackReference on single object reference (@ManyToOne side) and it works but I wasn't be able to retrieve all needed information (for example @ManyToOne reference). So i swapping @JsonBackReference on set structure and @JsonManagedReference on single object but I retrieve

No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.model.tablesField.TableUI["data"]->java.util.ArrayList[0]->com.domain.Car["carType"]->com.domain.CarType_$$_jvst744_f["handler"])

I tried also with @JsonIgnore on Set structure but it doesn't work for the same issues. This is my spring configuration

private Properties getHibernateProperties() {
        Properties properties = new Properties();
        properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
//      properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
        properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
        properties.put("hibernate.enable_lazy_load_no_trans",true);
        return properties;

and this is part of one of my several entities:

   /**
 * Car generated by hbm2java
 */
@Entity
@Table(name = "car", catalog = "ATS")
public class Car implements java.io.Serializable {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private Integer idCar;
        @JsonManagedReference
        private CarType carType;
        @JsonManagedReference
        private Fleet fleet;
        private String id;
        private int initialKm;
        private String carChassis;
        private String note;
        @JsonBackReference
        private Set<Acquisition> acquisitions = new HashSet<Acquisition>(0);

        public Car() {
        }

        public Car(CarType carType, Fleet fleet, int initialKm, String carChassis) {
            this.carType = carType;
            this.fleet = fleet;
            this.initialKm = initialKm;
            this.carChassis = carChassis;
        }

        public Car(CarType carType, Fleet fleet, String id, int initialKm, String carChassis, String note,
                Set<Acquisition> acquisitions) {
            this.carType = carType;
            this.fleet = fleet;
            this.id = id;
            this.initialKm = initialKm;
            this.carChassis = carChassis;
            this.note = note;
            this.acquisitions = acquisitions;
        }

        @Id
        @GeneratedValue(strategy = IDENTITY)

        @Column(name = "id_car", unique = true, nullable = false)
        public Integer getIdCar() {
            return this.idCar;
        }

        public void setIdCar(Integer idCar) {
            this.idCar = idCar;
        }

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "id_carType", nullable = false)
        public CarType getCarType() {
            return this.carType;
        }

        public void setCarType(CarType carType) {
            this.carType = carType;
        }

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "id_fleet", nullable = false)
        public Fleet getFleet() {
            return this.fleet;
        }

        public void setFleet(Fleet fleet) {
            this.fleet = fleet;
        }

        @Column(name = "id", length = 5)
        public String getId() {
            return this.id;
        }

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

        @Column(name = "initialKm", nullable = false)
        public int getInitialKm() {
            return this.initialKm;
        }

        public void setInitialKm(int initialKm) {
            this.initialKm = initialKm;
        }

        @Column(name = "carChassis", nullable = false, length = 20)
        public String getCarChassis() {
            return this.carChassis;
        }

        public void setCarChassis(String carChassis) {
            this.carChassis = carChassis;
        }

        @Column(name = "note", length = 100)
        public String getNote() {
            return this.note;
        }

        public void setNote(String note) {
            this.note = note;
        }

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
        public Set<Acquisition> getAcquisitions() {
            return this.acquisitions;
        }

        public void setAcquisitions(Set<Acquisition> acquisitions) {
            this.acquisitions = acquisitions;
        }

    }

one method that uses the query:

@Override
    @RequestMapping(value = { "/cars/{idFleet}"}, method = RequestMethod.GET)
    public @ResponseBody TableUI getCars(@PathVariable int idFleet) {   
        TableUI ajaxCall=new TableUI();
        try {   
            ajaxCall.setData(fleetAndCarService.findCarsByIdFleet(idFleet));
            return ajaxCall;
        } catch (QueryException e) {
            ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
            LOG.error("Threw exception in FleetAndCarControllerImpl::addCar :" + errorResponse.getStacktrace());
            return ajaxCall;
        }
    }

two class for the query:

public interface DefRdiRepository extends JpaRepository<DefRdi, Integer>{


    //@Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM DefRdi c WHERE c.parName = ?1 AND c.description= ?2")
    //Boolean existsByParNameAndDescription(String parName, String description);
    //Query method of spring, I put findBy and then the key of research 
    DefRdi findByParNameAndDescription(String parName, String description);
}

public interface CarRepository extends JpaRepository<Car, Integer>, CarRepositoryCustom {

    //Query method of spring, I put findBy and then the key of research 
    List<Car> findByFleetIdFleet(int idFleet);

}

Where is my error? I don't want Set object but only the single reference. The problem is only when I serialize. Thanks

UPDATE: I use @JSonIgnore on all set collectionts and Eager instead lazy ad all works fine, but is there a way to retrieve all the information only when I want, for example having two different query? So it doesn't work

@Override
@Transactional
public List<Car> findByFleetIdFleet(int idFleet) {
    List<Car> carList= carRepository.findByFleetIdFleet(idFleet);
    for (Car car:carList){
        Hibernate.initialize(car.getCarType());
        Hibernate.initialize(car.getFleet());
    }
    return carList; 
    //      return carRepository.findByFleetIdFleet(idFleet);
}

解决方案

All collections need to be fetched eagerly when loading them from data base, in order to get serialized by Spring. Make sure you fetch them eagerly (e.g. FetchMode.JOIN). You could also swap @JsonManagedReference from wanted fields with @JsonIgnore to black listed fields, Spring automatically serialises every field without annotation.

Update:

Changing the data repository to something like that should work, I am not sure it compiles, but I think you will get the point:

@EntityGraph(value = "some.entity.graph", type = EntityGraph.EntityGraphType.FETCH)
@Query(
        value = "SELECT c FROM Car c INNER JOIN FETCH c.acquisitions WHERE c.id = :idFleet"
)
public interface CarRepository extends JpaRepository<Car, Integer>, CarRepositoryCustom {

      //Query method of spring, I put findBy and then the key of research 
      List<Car> findByFleetIdFleet(int idFleet);

}

For more information look at this post and read the official documentation.

Workaround:

There seems to be a workaround, however fetching those collections eager like shown above should have a positive performance impact, since there is no need for loading proxies afterwards. Also no open transactions are needed at controller level.

这篇关于用Jackson注释映射hibernate实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆