Hibernate: не может получить связанный список - PullRequest
1 голос
/ 26 августа 2010

Сущность X имеет список сущности Y, а сущность Y имеет экземпляр сущности Z.

Соотношение между X и Y равно OneToMany, а соотношение между Y и Z равно ManyToOne.

Я хочу получить X, и все связанные с ним объекты также будут извлечены вместе с ними.

Какой HQL-запрос я пишу, чтобы получить всю цепочку, извлеченную сразу. В настоящее время его hibernateTemplate.find ("from X") . или какие анонации мне использовать для этого?

X = ServiceProvider, Y = BusinessLocations.java, Z = State.java

У меня есть сущности, аннотированные ниже, и вся цепочка сохраняется в базе данных, но когда я пытаюсь получить список Y (BusinessLocation), я получаю

ничего.

Что мне объединить X с Y и Y с Z?

Ниже приведены сущности x, Y и Z.

ServiceProvider.java

@Entity
public class ServiceProvider implements Serializable{

    private Long id;    
    private Set<BusinessLocation> businessLocations = new HashSet<BusinessLocation>();

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @OneToMany(mappedBy="serviceProvider", targetEntity=BusinessLocation.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    public Set<BusinessLocation> getBusinessLocations() {
        return businessLocations;
    }

    public void setBusinessLocations(Set<BusinessLocation> businessLocations) {
        this.businessLocations = businessLocations;
    }

    public boolean equals(Object obj) {
        if(!(obj instanceof ServiceProvider)) return false;
        ServiceProvider other = (ServiceProvider) obj;
        return new EqualsBuilder().append(businessLocations, other.businessLocations).isEquals();
    }
}

BusinessLocation.java

@Entity
public class BusinessLocation implements Serializable{

    private Long id;
    private String address;
    private String city;
    private State state;
    private String pincode;
    private ServiceProvider serviceProvider;

    public BusinessLocation() {     
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="state_id")
    public State getState() {
        return state;
    }
    public void setState(State state) {
        this.state = state;
    }   
    public void setPincode(String pincode) {
        this.pincode = pincode;
    }

    public String getPincode() {
        return pincode;
    }

    @ManyToOne
    @JoinColumn(name="serviceProvider_id")
    public ServiceProvider getServiceProvider() {
        return serviceProvider;
    }
    public void setServiceProvider(ServiceProvider serviceProvider) {
        this.serviceProvider = serviceProvider;
    }

    public boolean equals(Object obj) {
        if( !(obj instanceof BusinessLocation)) return false;
        BusinessLocation other = (BusinessLocation) obj;        
        return new EqualsBuilder().append(address, other.address).append(city, other.city).append(state, other.state).append(pincode, 

other.pincode).append(serviceProvider, other.serviceProvider).isEquals();
    }

    public int hashCode() {
        return new HashCodeBuilder().append(address).append(city).append(state).append(pincode).append(serviceProvider).toHashCode();
    }
}

State.java

@Entity
public class State implements Serializable {

    private Long id;
    private String abbreviatedName;
    private String name;
    private List<BusinessLocation> businessLocations;

    @Id
    @GeneratedValue 
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getAbbreviatedName() {
        return abbreviatedName;
    }
    public void setAbbreviatedName(String abbreviatedName) {
        this.abbreviatedName = abbreviatedName;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }


    @OneToMany(mappedBy="state", targetEntity=BusinessLocation.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    public List<BusinessLocation> getBusinessLocations() {
        return businessLocations;
    }
    public void setBusinessLocations(List<BusinessLocation> businessLocations) {
        this.businessLocations = businessLocations;
    }

    public boolean equals(Object obj) {
        if(! (obj instanceof State)) return false;
        State other = (State) obj;
        return new EqualsBuilder().append(abbreviatedName, other.abbreviatedName).append(name, other.name).append(businessLocations, 

other.businessLocations).isEquals();
    }

    public int hashCode() {
        return new HashCodeBuilder().append(name).append(abbreviatedName).append(businessLocations).toHashCode();
    }

}

Может ли кто-нибудь помочь мне здесь?

Спасибо

Ответы [ 2 ]

0 голосов
/ 26 августа 2010

У меня есть сущности, аннотированные ниже, и вся цепочка сохраняется в базе данных, но когда я пытаюсь получить список Y (BusinessLocation), я получаю ... ничего

Вы должны активировать ведение журнала SQL, чтобы увидеть, что происходит, и проверить данные, потому что часть аннотации выглядит правильно:

  • один-ко-многим между ServiceProvider и BusinessLocation равен EAGER
  • значение «многие-к-одному» между BusinessLocation и State равно EAGER (по умолчанию)

Таким образом, вся цепочка должна быть извлечена с нетерпением.Если это не то, что происходит, вы можете проверить данные и SQL, отсюда и предложение.

В качестве альтернативы ассоциациям EAGER вы можете использовать FETCH JOIN для предварительной выборки связанных данных:

FROM ServiceProvider provider
  INNER JOIN FETCH provider.businessLocations location
  LEFT JOIN FETCH location.state

Но учтите, что JPA 1.0 не позволяет вложенных выборок соединения в JPQL, это специфично для Hibernate.

Ссылки

  • Справочное руководство по ядру Hibernate
  • Спецификация JPA 1.0
    • Раздел 9.1.22 «Аннотация ManyToOne»
    • Раздел 4.4.5.3 «Соединения извлечения»
0 голосов
/ 26 августа 2010

А как же:

Query q - entityManager.createQuery("Select x from ServiceProvider x inner join x.businessLocations as y and inner join y.state as z where x.id = ?1");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...