Java 用Jackson注释映射hibernate实体
我正在使用Spring、hibernate和MySql,但在查询结果的序列化方面存在一些问题。 首先,在我的实体中,我在集合结构(@OneToMany side)上添加了@JsonManagedReference,在单个对象引用(@ManyToOne side)上添加了@JsonBackReference,它可以工作,但我无法检索所有需要的信息(例如@ManyToOne reference)。 所以我在集合结构上交换@JsonBackReference,在单个对象上交换@JsonManagedReference,但我检索Java 用Jackson注释映射hibernate实体,java,mysql,spring,hibernate,jackson,Java,Mysql,Spring,Hibernate,Jackson,我正在使用Spring、hibernate和MySql,但在查询结果的序列化方面存在一些问题。 首先,在我的实体中,我在集合结构(@OneToMany side)上添加了@JsonManagedReference,在单个对象引用(@ManyToOne side)上添加了@JsonBackReference,它可以工作,但我无法检索所有需要的信息(例如@ManyToOne reference)。 所以我在集合结构上交换@JsonBackReference,在单个对象上交换@JsonManagedR
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"])
我也尝试过在Set结构上使用@JsonIgnore,但它不能解决相同的问题。
这是我的spring配置
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;
这是我的几个实体之一的一部分:
/**
* 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;
}
}
查询的两个类:
@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;
}
}
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);
}
公共接口定义库扩展了JpaRepository{
//@查询(“当COUNT(c)>0时选择CASE,然后选择true,否则从DefRdi c结束,其中c.parName=?1和c.description=?2”)
//Boolean existsByParNameAndDescription(字符串名称、字符串描述);
//spring的查询方法,我把findBy和然后的关键研究
DefRdi findByParNameAndDescription(字符串名称、字符串描述);
}
公共接口CarRepository扩展了JpaRepository、CarRepositoryCustom{
//spring的查询方法,我把findBy和然后的关键研究
列出FindByFleetId车队(int idFleet);
}
我的错误在哪里?我不想要Set对象,只想要单个引用。问题只是当我序列化时。谢谢
更新:
我在所有集合集合上使用@JSonIgnore,而使用Eager代替lazy,这一切都很好,但是有没有一种方法可以仅在我需要时检索所有信息,例如使用两个不同的查询?
所以它不起作用
@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);
}
@覆盖
@交易的
公共列表FindByFleetId车队(int idFleet){
列表carList=carRepository.findbyfleetidfilet(idFleet);
用于(汽车:carList){
初始化(car.getCarType());
初始化(car.getFleet());
}
返回卡利斯特;
//返回结转库。findByFleetIdFleet(idFleet);
}
当从数据库加载集合时,需要急切地获取所有集合,以便通过Spring进行序列化。确保您急切地获取它们(例如FetchMode.JOIN)。您还可以将@JsonManagedReference从带有@JsonIgnore的通缉字段交换到黑名单字段,Spring会自动序列化每个字段,而无需注释
更新:
将数据存储库更改为类似的方式应该会起作用,我不确定它是否可以编译,但我认为您会明白这一点:
@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);
}
@EntityGraph(value=“some.entity.graph”,type=EntityGraph.EntityGraphType.FETCH)
@质疑(
value=“从车辆c内部连接获取c.c中选择c,其中c.id=:idFleet”
)
公共接口CarRepository扩展了JpaRepository、CarRepositoryCustom{
//spring的查询方法,我把findBy和然后的关键研究
列出FindByFleetId车队(int idFleet);
}
有关更多信息,请参阅帖子并阅读
解决方法:
似乎存在一个问题,但是获取像上面所示的集合应该会对性能产生积极的影响,因为之后不需要加载代理。在控制器级别也不需要打开的事务。我尝试在黑名单字段(所有集合)上只使用@JsonIgnore,但不起作用。我用fetchType更新了上面的代码,我正在使用LazyType,这就是问题所在。当Spring想要序列化您的集合时,由于延迟加载,除了代理之外没有集合。您有两种选择:在需要的加载时间(推荐)立即获取集合,或者将映射类型更改为“立即”。如何才能立即获取集合?在没有@JsonIgnore的所有外部对象上使用Hibernate.initialize?否则,如果我使用model.addAttribute(“fleets”,fleetAndCarService.getFleets())就不会出现任何问题。请说明如何加载它们、条件、HQL、Spring数据、JDBC。。。?我更新了我的第一篇文章和上面的问题,如果我必须对所有对象使用hibernnate.initialize,我可以使用eager,是一样的吗?