Полиморфное «get» с использованием hibernate, многие к одному, InheritanceType.JOINED - PullRequest
5 голосов
/ 19 октября 2011

У меня есть что-то вроде этого ..

Класс автомобиля с одним сиденьем из множества мест. Сиденье имеет подкласс LeatherSeat.

public class Car {
  private Seat seat;
  ...
  @ManyToOne(fetch = FetchType.LAZY)
  public Seat getSeat() {
    return seat;
  }
  ...
}

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Seat {
  private String id;
  private String color;
} 

@Entity
public class LeatherSeat extends Seat {
    private String leatherType;
}

Когда я создаю свой автомобиль и делаю сиденье моего автомобиля кожаным сиденьем, оно правильно сохраняет все данные на БД. Когда я хочу получить свой автомобиль (используя критерии или список запросов) и читаю getSeat (), Seat всегда является просто Seat, а не LeatherSeat. Я не могу разыграть (исключение) и, похоже, должен вручную получить LeatherSeat по id.

Это ограничение использования типа наследования JOINED или я что-то упустил. Как мне получить Seat как LeatherSeat?

Ответы [ 2 ]

2 голосов
/ 12 июня 2012

В случае LAZY, место будет «прокси», которое создается при создании экземпляра Car.В то время Hibernate не знает, будет ли сиденье кожаным или нет.

Когда вы пройдете через свойство и оно лениво загружено, то Hibernate узнает, что сиденье кожаное, но не может измениться задним числомкласс прокси.Тем не менее, все данные есть.Место будет реагировать как LeatherSeat, если вы переопределили какие-либо методы.

Если вам действительно нужно привести этот объект к LeatherSeat, вы можете распаковать прокси с помощью http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/engine/PersistenceContext.html#unproxy(java.lang.Object)

См. Этот блог дляподробнее о том, почему прокси всегда будет Seat, а не LeatherSeat: http://sessionfactory.blogspot.co.uk/2010/08/hacking-lazy-loaded-inheritance.html

Это кратко описано в документации по Hibernate здесь: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching-proxies

1 голос
/ 19 октября 2011

Похоже, что если вы делаете ленивую выборку, как вы делаете с getSeat, вы всегда будете получать только родителя, а не подкласс.Я попробовал этот же пример с FetchType.EAGER и getSeat правильно возвращает LeatherSeat.

Я не уверен, почему hibernate может получить Автомобиль с LeatherSeat, когда для получения EAGER, но hibernate не может получить его, когда делает LAZY.Похоже, что-то там сломано.

В InheritanceType есть заявка на столбцы дискриминатора, в которой указывается точка зрения на этот сценарий.https://hibernate.onjira.com/browse/ANN-140 но билет был отклонен, указывая на то, что режим гибернации был слишком элегантным, чтобы нуждаться в дискриминаторе для InheritanceType.JOINED.Тем не менее он не может правильно вернуть подклассы при отложенных выборках.

Тогда этот билет https://hibernate.onjira.com/browse/HHH-271?focusedCommentId=44089#comment-44089 более специфичен для этой проблемы, и там был ответ: «Как мы должны знать, какой подкласс получить при ленивом извлечении?»

Оба билета старые и были отклонены.Похоже, проблема для меня.Но сейчас вам придется перейти на другой тип наследования или использовать нетерпеливый тип выборки, так как это соответствует дизайну hibernate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...