Java jackson-不序列化惰性对象
我有一个实体:Java jackson-不序列化惰性对象,java,json,spring,jackson,jackson-modules,Java,Json,Spring,Jackson,Jackson Modules,我有一个实体: @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Column private String title; @OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL) p
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column
private String title;
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
private List<Genre> genre;
}
谢谢
我不能将它标记为JsonIgnore,因为它将永远不会被序列化。有时,我需要检索书籍的体裁,到那时,我将在查询中使用“fetch join”,这样它就不会为空。可能这与
我没有使用jackson数据类型hibernate,但是我解决了同样的问题,通过使用DTO而不是直接序列化hibernate对象,从图片中获取持久集合。像推土机这样的工具可以帮你解决这个问题。或者,我写了一个类似这样的映射
如果您只是想体验DTO的样子,那么可以将卸载的持久集合替换为常规的空集合,如books.setgreen(new ArrayList());不幸的是,我不知道如何判断延迟加载的对象是否已加载,因此无法自动执行此重新分配。替换持久集合的位置需要由您根据具体情况确定。您可以使用:
@实体
@JsonFilter(“书”)
公共课堂用书{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@纵队
私有字符串标题;
@OneToMany(fetch=FetchType.LAZY,mappedBy=(“电影”),cascade=CascadeType.ALL)
私人列表体裁;
}
@实体
@JsonFilter(“流派”)
公共课体裁{
...
}
然后在控制器中指定要过滤的内容:
@Controller
public class BookController {
@Autowired
private ObjectMapper objectMapper;
@Autowird
private BookRepository bookRepository;
@RequestMapping(value = "/book", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public ResponseEntity<String> getBooks() {
final List<Book> books = booksRepository.findAll();
final SimpleFilterProvider filter = new SimpleFilterProvider();
filter.addFilter("Book", SimpleFilterProvider.serializeAllExcept("Genre");
return new ResponseEntity<>(objectMapper.writer(filter).writeValueAsString(books), HttpStatus.OK)
}
}
@控制器
公共类图书管理员{
@自动连线
私有对象映射器对象映射器;
@自动布线
私人书库;
@RequestMapping(value=“/book”,method=RequestMethod.GET,products=“application/json”)
@应答器
公共响应getBooks(){
final List books=booksRepository.findAll();
最终SimpleFilterProvider筛选器=新SimpleFilterProvider();
filter.addFilter(“Book”,SimpleFilterProvider.serializeAllExcept(“流派”);
返回新的ResponseEntity(objectMapper.writer(filter).writeValueAsString(books),HttpStatus.OK)
}
}
通过这种方式,您可以控制何时要在运行时过滤惰性关系您可以使用Jackson
@JsonInclude
注释来实现这一点
根据,如果字段值为null或空,则可以使用简单注释指定是否包含注释属性
默认情况下,它是jsonclude.Include.ALWAYS
,这意味着即使延迟未加载的值为null,Jackson也会包含该属性
指定不包含空值或null值可以显著减少JSON响应的大小,并提供所有好处
如果要更改此行为,可以在类级别或单个属性/getterMethod级别添加注释
如果字段为空,请尝试将以下批注添加到不希望包含的字段中:
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
private List<Genre> genre;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@OneToMany(fetch=FetchType.LAZY,mappedBy=(“电影”),cascade=CascadeType.ALL)
私人列表体裁;
您可以使用Gson而不是ObjectMapper,并在定义实体时将字段标记为“transient”
公共课堂教材{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@纵队
私有字符串标题;
@OneToMany(fetch=FetchType.LAZY,mappedBy=(“电影”),cascade=CascadeType.ALL)
私有**临时**列表类型;
}
使用
gson.toJson(book)
反序列化时,gson不会反序列化该元素。默认情况下,您可以使用spring配置禁用强制延迟加载
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
Hibernate5Module hibernate5Module = new Hibernate5Module();
hibernate5Module.configure(Feature.FORCE_LAZY_LOADING, false);
// Enable below line to switch lazy loaded json from null to a blank object!
//hibernate5Module.configure(Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true);
mapper.registerModule(hibernate5Module);
return mapper;
}
}
[Transient][1][1]:尝试使用此主题获取您的anserw;)嗨@Fincio,我无法将流派字段设置为Transient,因为我需要它在数据库中持久化。嗯,@JsonIgnoreProperties({“流派”})或@JsonIgnoreI如何更新我的帖子?为什么我不能这样做。谢谢你能找到解决办法吗?我也面临同样的问题。如果您有任何问题,请提供帮助。这在SpringJPA+SpringREST控制器解决方案中对我不起作用。当JSON序列化发生时,仍然会发生延迟抓取…这不是JPA2.1与EclipseLink结合使用的正确答案!问题很明显,Jackson通过调用getter来检查属性是否为“NON_EMPTY”,这会触发延迟加载!不幸的是,没有AccesType“Field”Json注释,这会有所帮助。顺便说一句,我认为Moxy支持这一点(我认为它使用JAXB注释)。@RonyeVernaes在添加了
HibernateModule
Bean之后,它对我有效。请看chrismarx在中的回答。我可以确认这与Zeemee的额外信息有效。在Spring Boot中,您需要将Jackson Hibernate5模块添加到pom.xml中并注册bean;addFilter()的第二个参数应该是SimpleBeanPropertyFilter.serializeAll。。。不是SimpleFilterProvider。序列化所有。。。班
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
private List<Genre> genre;
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column
private String title;
@OneToMany(fetch = FetchType.LAZY, mappedBy = ("movie"),cascade = CascadeType.ALL)
private **transient** List<Genre> genre;
}
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
Hibernate5Module hibernate5Module = new Hibernate5Module();
hibernate5Module.configure(Feature.FORCE_LAZY_LOADING, false);
// Enable below line to switch lazy loaded json from null to a blank object!
//hibernate5Module.configure(Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS, true);
mapper.registerModule(hibernate5Module);
return mapper;
}
}