1

我使用过 Spring 和 Hibernate。现在看看 Spring Data JPA (2.0.3) 和 JPA 2.2

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;
   }
}

代理票务类别

@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);
    }    
}

在 Service 上进行调试时,查询似乎急切地获取所有延迟加载的属性 - 代理、代理TicketCategories - 及其所有内部延迟加载的属性,这会导致JSON 序列化错误

只需要获取这些

AgencyTicketTypes [
                   {
                     id, name,
                     agencyTicketCategories [
                                              {id,name,price},....
                                            ]
                   },.....    
                 ]

我可以这样做@EntityGraph吗?我错过了什么?

4

3 回答 3

0

您可以使用杰克逊注释@JsonBackReference/ @JsonManagedReference。它们解决了对象模型中具有双向链接的无限递归问题。据我了解,这是你的情况。

有关更多信息,请参阅http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion

于 2018-02-06T06:38:05.430 回答
0

Specifying lazy loading is only a hint for the JPA provider. Depending on the provider you use (Hibernate, EclipseLink etc.) it may be completely ignored and the dependencies may be eagerly fetched.

What you need to do is configure how your classes are mapped to json. Assuming you are using Jackson you may need to use annotations like @JsonIgnore or @JsonView. You may also map your class that only has the fields you need.

于 2018-02-06T06:23:59.823 回答
0

需要指出的一件事是,在事务打开(触摸集合)时进行调试会导致它被加载,即使它没有实时加载.. 另一件事是,正如@Apokralipsa 提到的那样,延迟加载只是一个提示可以完全忽略它,并且永远不应该依赖于您使用的任何技术

于 2018-02-06T08:21:19.497 回答