我使用过Spring和Hibernate。现在看看带有JPA 2.2的Spring Data JPA(2.0.3)
AgencyTicketType
@Entity
@Table(name = "agency_ticket_type", catalog = "test")
public class AgencyTicketType implements java.io.Serializable {
private Long id;
private String name;
private Agency agency;
private Set<AgencyTicketCategory> agencyTicketCategories = new HashSet<AgencyTicketCategory>(0);
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "name", nullable = false, length = 100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "agency_id", nullable = false)
public Agency getAgency() {
return this.agency;
}
public void setAgency(Agency agency) {
this.agency = agency;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "agencyTicketType")
public Set<AgencyTicketCategory> getAgencyTicketCategories() {
return this.agencyTicketCategories;
}
public void setAgencyTicketCategories(Set<AgencyTicketCategory> agencyTicketCategories) {
this.agencyTicketCategories = agencyTicketCategories;
}
}
AgencyTicketCategory
@Entity
@Table(name = "agency_ticket_category", catalog = "waytest")
public class AgencyTicketCategory implements java.io.Serializable {
private Long id;
private AgencyTicketType agencyTicketType;
private String name;
private BigDecimal price;
private Set<TripTicket> tripTickets = new HashSet<TripTicket>(0);
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "agency_ticket_type_id", nullable = false)
public AgencyTicketType getAgencyTicketType() {
return this.agencyTicketType;
}
public void setAgencyTicketType(AgencyTicketType agencyTicketType) {
this.agencyTicketType = agencyTicketType;
}
@Column(name = "name", nullable = false, length = 100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "price", nullable = false, precision = 8)
public BigDecimal getPrice() {
return this.price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "agencyTicketCategory")
public Set<TripTicket> getTripTickets() {
return this.tripTickets;
}
public void setTripTickets(Set<TripTicket> tripTickets) {
this.tripTickets = tripTickets;
}
}
存储库
public interface TicketTypeRepository extends JpaRepository<AgencyTicketType, Long> {
@EntityGraph(attributePaths={ "agencyTicketCategories" }, type=EntityGraphType.LOAD)
@Query("select type from AgencyTicketType type where type.agency.code=?1")
List<AgencyTicketType> findByAgency(String agencyCode);
}
服务
@Service
public class TicketServiceImpl implements TicketService {
@Autowired private TicketTypeRepository ticketType;
@Transactional(readOnly=true)
@Override
public List<AgencyTicketType> findByName(String code) {
return ticketType.findByAgency(code);
}
}
在服务上调试时,看起来,查询急切地获取所有延迟加载的属性 - agency,agencyTicketCategories - 以及所有内部延迟加载的属性,这会导致 JSON serilization error < /强>
只需要获取这些
AgencyTicketTypes [
{
id, name,
agencyTicketCategories [
{id,name,price},....
]
},.....
]
我可以使用@EntityGraph
执行此操作吗?我缺少什么?
答案 0 :(得分:0)
指定延迟加载只是JPA提供程序的提示。根据您使用的提供程序(Hibernate,EclipseLink等),可能会完全忽略它,并且可能会急切地获取依赖项。
您需要做的是配置类映射到json的方式。假设您使用的是Jackson,则可能需要使用@JsonIgnore
或@JsonView
等注释。您也可以映射只有您需要的字段的类。
答案 1 :(得分:0)
您可以使用杰克逊注释@JsonBackReference
/ @JsonManagedReference
。它们解决了对象模型中双向链接的无限递归问题。据我所知,这是你的情况。
有关详细信息,请参阅http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion。
答案 2 :(得分:0)
有一点需要注意的是,在事务处于打开状态时进行调试(触摸集合)会导致它被加载,即使实时它也没有...另一件事就是@Apokralipsa提到的,LAZY加载只是一个可以完全忽略的提示,不应该依赖于你正在使用的任何技术