2010-09-21 6 views
0

У меня есть эти 2 стола Учителя и контакт, у учителя может быть x Контакты. Итак, мы смотрим на ассоциацию @OneToMany.Hibernate - OneToMany - Несколько столбцов

Таблицы Структура:

пользователя [идентификатор пользователя, имя пользователя, адрес электронной почты, ...]
Контакт [ContactID, CONTACTNAME, хол, переменная типа RefType ...]

Я хочу загрузите из моего User Class все контакты пользователя. Для этого я хотел бы сделать запрос как

Select * from contact as c WHERE c.ref=8240 AND c.reftype='T'; 

8240 является случайным Идент и переменная типа RefType T является для учителя. Поскольку эта контактная таблица используется также для контактов в школе и/или любого другого типа клиентов, которые мы могли бы иметь. Проблема в том, что я понятия не имею, как это сделать с Hibernate. Должен ли я использовать embedbedId? Или JoinColumns?

То, что я сделал до сих пор, чтобы связать мой учитель к контактам, имеющим contact.ref=teacher.teacherid, но то, что я хочу это:

contact.ref=teacher.teacherid AND contact.reftype='T' 

Как я могу это сделать?

Вот мой код Teacher.class

private Integer teacherid; 
private Set<Contact> contact; 
@Id 
@GeneratedValue(strategy = IDENTITY) 
@Column(name = "teacherid", unique = true, nullable = false) 
public Integer getTeacherId() { 
    return teacherid; 
} 

@OneToMany(fetch = FetchType.EAGER) 
@JoinColumns({ 
    @JoinColumn(name="ref"), 
}) 
public Set<Contact> getContact() { 
    return contact; 
} 

public void setContact(Set<Contact> contact) { 
    this.contact = contact; 
} 

Contact.class

@Entity 
@Table(name = "contact") 
public class Contact implements java.io.Serializable { 

    private Integer contactid; 
    private String contactname; 
    private String contacttype; 
    private String reftype; 
    private int ref; 

    /*private Teacher teacher; 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumns({ 
     @JoinColumn(name = "ref"), 
     @JoinColumn(name = "reftype") 
    }) 
    public Teacher getTeacher() { 
     return teacher; 
    } 
    public void setTeacher (Teacher teacher) { 
     this.teacher= teacher; 
    } 
*/ 
    private Set<ContactItem> contactItems; 
    private Set<ContactAddress> contactAddressess; 

    @OneToMany(fetch=FetchType.EAGER) 
    @JoinColumn(name="contactid") 
    public Set<ContactItem> getContactItems(){ 
     return contactItems; 
    } 

    public void setContactItems(Set<ContactItem> contactItems) { 
     this.contactItems = contactItems; 
    } 

    @OneToMany(fetch=FetchType.EAGER) 
    @JoinColumn(name="contactid") 
    public Set<ContactAddress> getContactAddressess(){ 
     return contactAddressess; 
    } 

    public void setContactAddressess(Set<ContactAddress> contactAddressess) { 
     this.contactAddressess = contactAddressess; 
    } 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(name = "contactid", unique = true, nullable = false) 
    public Integer getContactid() { 
     return this.contactid; 
    } 

    public void setContactid(Integer contactid) { 
     this.contactid = contactid; 
    } 

    @Column(name = "contactname", nullable = false) 
    public String getContactname() { 
     return this.contactname; 
    } 

    public void setContactname(String contactname) { 
     this.contactname = contactname; 
    } 

    @Column(name = "contacttype", nullable = false) 
    public String getContacttype() { 
     return this.contacttype; 
    } 

    public void setContacttype(String contacttype) { 
     this.contacttype = contacttype; 
    } 

    @Column(name = "reftype", nullable = false, length = 1) 
    public String getReftype() { 
     return this.reftype; 
    } 

    public void setReftype(String reftype) { 
     this.reftype = reftype; 
    } 

    @Column(name = "ref", nullable = false) 
    public int getRef() { 
     return this.ref; 
    } 

    public void setRef(int ref) { 
     this.ref = ref; 
    } 

    public String toString(){ 
     return "\n#"+this.contactname+" : ("+this.ref+"-"+this.reftype+") \n" 
        +"#Items-----\n"+getContactItems()+"\n" 
        +"#Address---\n"+getContactAddressess()+"\n"; 
    } 
} 
+0

Является ли 'учитель'' пользователем' (почему вы показываете таблицу пользователя, если нет)? У вас есть какое-то наследство? У вас есть ограничение внешнего ключа в столбце 'ref'? –

+0

Даже с вашими изменениями, я думаю, что мой ответ ниже по-прежнему в целом правильный. Вам нужно будет изменить данные, чтобы они соответствовали вашей ситуации. –

+0

Я лично считаю, что в дизайне что-то не так. Просьба уточнить связь между пользователем/учителем и контактом, это важно. –

ответ

0

Предполагая, что Teacher является User, и что каждый пользователь имеет contacts.

User.class

@OneToMany(mappedBy = "user", targetEntity = Contact.class, orphanRemoval=true) 
@Cascade(CascadeType.ALL) 
private Set<Contact> contacts = new ConcurrentSkipListSet<Contact>(); 

//No setContacts here. 

Contact.class

@ManyToOne 
private User user; 

public void setUser(User user){ 
this.user = user; 
} 

Вот так.

+0

Я не думаю, что ваше решение будет работать. Поскольку я не вижу, как вы управляете своими особыми отношениями между классом «Пользователь» (Учитель) и «Контактным классом». Отношения: teacher.teacherid = contact.ref AND contact.reftype = 'T'. – deluxouss

0

Во-первых, поскольку есть таблица пользователей и таблица Учителя (учителя, похоже, являются подмножеством пользовательских строк, обозначаемых столбцом типа). У меня не было бы таблицы User и модели Teacher. Вместо этого у меня была бы только модель User. Hibernate много проще, если вы делаете что-то типа Hibernate, который является одной моделью для таблицы с моделью с тем же именем. Например, если вы это сделаете, вы можете использовать инструмент для автоматического генерации (реинжиниринг) всех ваших классов моделей. Это означает, что инструмент Hibernate будет смотреть на ваши таблицы, внешние ключи и т. Д. И генерировать подходящий код Java для ваших таблиц. Очень удобно, когда вы начинаете делать изменения таблицы.

Обычно вы переделываете классы моделей. Поскольку они генерируются машиной, вы не хотите их менять, потому что изменения будут переписаны в следующий раз, чтобы реконструировать модели. То, что я делаю для таких условий, как ваш, заключается в создании класса DAO - Data Access Object или DAO.

public class UserDAO { 
    public static User getTeacher(EntityManager em, Long id) { 
     try { 
     IForgotTheType query = em.createQuery("User from User user, Contact contact where contact.ref=user.teacherid AND contact.reftype='T' and User.id=:id"); 
     query.setParameter("id", id); 
     return (User) query.getSingleResult(); 
     } catch (NoResultException e) { 
      return null; 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
} 

Очевидно, что я не уверен в вашей структуре таблицы и именах столбцов, но вы получите эту идею.Вы можете увидеть, где я вставил ваш код в запрос выше. Теперь вы можете получить учителя, просто вызывая UserDAO.getTeacher(). Используйте DAO - иначе у вас будет Hibernate-код везде в вашем коде, что упрощает обслуживание.

Check out section 3.4 of this.

+0

Спасибо, что Тони, Но теперь у меня есть дополнительные вопросы. Как мне получить доступ к моему контактному объекту из объекта User (Teacher)? И как выглядит мой класс User? Каким он должен быть? – deluxouss

+0

Для доступа к контактному объекту вы увидите Hibernate shine: 'userInstance.getContact();' возвращает экземпляр Contact, полученный из базы данных. –

+0

Каким должно быть отображение на пользователе? Вот что я делаю. (Это отказ от ответственности!) 1. Определите схему базы данных правильно. Это означает, что у вас будет таблица User с обычными вещами, включая первичный ключ, назначенный базой данных с использованием последовательности. Должен быть столбец contact_id. Затем создайте таблицу контактов, в которой есть контакты. Определите внешний ключ, используя столбец user.contact_id. Затем я перепроектирую модель. Я сделал два больших проекта, используя Hibernate. Я никогда не вручную кодировал модель. Обратная инженерия - это победа. –