Hibernate;сопоставить родителя с набором детей с составным идентификатором - PullRequest
1 голос
/ 06 марта 2012

Я не смог найти точный ответ на мою проблему в других постах.У меня есть родительские и дочерние объекты (Sender и SenderConfig, соответственно).У дочернего элемента есть составной первичный ключ, состоящий из родительского объекта и другого произвольного объекта, смоделированного в соответствии с бизнес-правилами.Я хочу иметь возможность получить все SenderConfig для Sender, поэтому я добавил ссылку Set на SenderConfig's в объекте Sender и пометил ее @OneToMany (см. Ниже).Я создал строку в таблице SENDER и соответствующую строку в таблице SENDER_CONFIG вручную.Однако, когда я пытаюсь загрузить отправителя через em.find (Sender.class, 1L), он выполняет запрос около 50 раз, а затем молча завершается неудачей.Я разместил соответствующие фрагменты кода, а также запрос, который запускает Hibernate.Любая помощь будет принята с благодарностью!

Родитель:

@Entity
@Table( name = "SENDER" )
public class Sender {

private Long id;
private String name;
private String description;
private Set<SenderConfig> senderConfigSet;

@Id
@GenericGenerator(name = "generator", strategy = "native", parameters = { @Parameter(name = "sequence", value = "SEQ_SENDER") })
@GeneratedValue(strategy = AUTO, generator = "generator")
@Column(name = "ID", nullable = false, insertable = true, updatable = true)
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Column(name = "NAME", unique = true, nullable = false, insertable = true, updatable = true, length = 32)
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Column(name = "DESCRIPTION", unique = false, nullable = false, insertable = true, updatable = true, length = 128)
public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, mappedBy = "id.sender")
public Set<SenderConfig> getSenderConfigSet() {
    return senderConfigSet;
}

public void setSenderConfigSet(Set<SenderConfig> senderConfigSet) {
    this.senderConfigSet = senderConfigSet;
}

@Override
public int hashCode() {
    return id.hashCode();
}

@Override
public boolean equals(Object o) {
    if(!(o instanceof Sender)) return false;
    return ((Sender)o).id.equals(id);
}

}

Ребенок:

@Entity
@Table( name = "SENDER_CONFIG")
public class SenderConfig implements Serializable {

private SenderConfigPK id;

@Embeddable
public static class SenderConfigPK implements Serializable {

    private Sender sender;
    private FauxDataType fauxDataType;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "ID_SENDER", nullable = false, insertable = true, updatable = true, referencedColumnName="ID")
    @ForeignKey(name = "FK_SENDER_CONFIG_1")
    public Sender getSender() {
        return sender;
    }

    public void setSender(Sender sender) {
        this.sender = sender;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "ID_FAUX_DATA_TYPE", nullable = false, insertable = true, updatable = true, referencedColumnName="ID")
    @ForeignKey(name = "FK_SENDER_CONFNIG_2")
    public FauxDataType getFauxDataType() {
        return fauxDataType;
    }

    public void setFauxDataType(FauxDataType fauxDataType) {
        this.fauxDataType = fauxDataType;
    }

    @Override
    public int hashCode() {
        return Integer.valueOf(sender.hashCode() + "" + fauxDataType.hashCode());
    }

    @Override
    public boolean equals(Object obj) {
        if(!(obj instanceof SenderConfigPK)) return false;
        SenderConfigPK pk = (SenderConfigPK)obj;
        if(!sender.equals(pk.sender)) return false;
        if(!fauxDataType.equals(pk.fauxDataType)) return false;
        return true;
    }

}

@EmbeddedId
public SenderConfigPK getId() {
    return id;
}

public void setId(SenderConfigPK id) {
    this.id = id;
}

@Override
public int hashCode() {
    return id.hashCode();
}

@Override
public boolean equals(Object o) {
    if(!(o instanceof SenderConfig)) return false;
    return id.equals(((SenderConfig)o).id);
}

}

Запрос гибернации (который возвращает правильные результаты при запуске вручную):

select
    sender0_.ID as ID75_1_,
    sender0_.DESCRIPTION as DESCRIPT2_75_1_,
    sender0_.NAME as NAME75_1_,
    senderconf1_.ID_SENDER as ID7_3_,
    senderconf1_.ID_FAUX_DATA_TYPE as ID6_3_,
    senderconf1_.ID_FAUX_DATA_TYPE as ID6_76_0_,
    senderconf1_.ID_SENDER as ID7_76_0_
from
    SENDER sender0_ 
left outer join
    SENDER_CONFIG senderconf1_ 
        on sender0_.ID=senderconf1_.ID_SENDER 
where
    sender0_.ID=? 
...