如何在Hibernate中正确映射一对多关系?

时间:2016-02-22 20:55:47

标签: java hibernate

我有两个实体,Event(实际上是电影中的电影)和Ticket

@Entity
public class Event {

    @Id
    @GeneratedValue
    private Integer id;
    @OneToOne
    private Movie movie;
    @Embedded
    private Auditorium auditorium;
    private LocalDateTime startDateTime;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "event")
    private List<Ticket> tickets = new ArrayList<>();
// getters/setters, etc.

Event包含要出售的Ticket个列表,每个Ticket应指向一个Event

@Entity
public class Ticket {

    @Id
    @GeneratedValue
    private Integer id;
    @ManyToOne(cascade = CascadeType.ALL, targetEntity = Event.class)
    private Event event;
    @OneToOne
    private User user;
    @Embedded
    private Seat seat;
    private TicketState state;
    private Float price;
// getters/setters, etc.

我有EventService这样的方法(Auditorium只包含座位数和VIP座位数),bookingDao只保存Ticket在DB中:

@Override
@Transactional
public boolean assignAuditorium(Integer eventId, Auditorium auditorium, LocalDateTime datetime) {
        for (Event event : getAll()) {
            if (auditorium.equals(event.getAuditorium()) && intersectsWithAnotherEvent(event, datetime)) {
                return false;
            }
        }
        Event currentEvent = getById(eventId);
        currentEvent.setAuditorium(auditorium);
        currentEvent.setStartDateTime(datetime);
        List<Ticket> tickets = currentEvent.getTickets();
        Integer seatsNumber = auditorium.getSeatsNumber();
        List<Integer> vipSeats = auditorium.getVipSeats();
        for (int i = 1; i <= seatsNumber; i++) {
            Ticket ticket = new Ticket();
            ticket.setEvent(currentEvent);
            ticket.setState(TicketState.FREE);
            ticket.setSeat(new Seat(i, vipSeats.contains(i) ? SeatStatus.VIP : SeatStatus.STANDARD));
            bookingDao.create(ticket);
            tickets.add(ticket);
        }
        return true;
    }
}

问题是:创建之后,f.e。 10 Ticket&#39; s(根据Auditorium中的席位数量){{1}我有10个(!!!)相同的Event&#39; s如果eventService.getAll()列表的大小为10,则每个故障单都有Ticket(正如预期的那样),而不是Event

那么,如何正确映射这些实体以获得一个事件到多个票证?谢谢!

更新 Event

的实施
getAll()

enter image description here

UPDATE2 我在@Override @Transactional public List<Event> getAll() { return eventDao.getAll(); } @Override public List<Event> getAll() { return sessionFactory.getCurrentSession().createCriteria(Event.class).list(); } 方法结束后就有这样的图片,假设,然后assignAuditorium结束工作。我在这个方法中@Transactional显示一个getAll(),其Event列表符合预期。也许它会有所帮助。

1 个答案:

答案 0 :(得分:2)

这是由您的一对多关联中的EAGER提取类型引起的。我的第一个建议是让它保持懒惰:你真的不想每次想要获得有关事件的信息时加载250张票。我甚至可能会避开OneToMany协会。

但是,为了解决这个问题,你需要使用distinct。通过向条件查询添加DistinctRootEntity结果转换器,或者最好使用JPQL查询而不是条件查询:

select distinct e from Event e