如何使用hibernate正确建模复杂的层次结构和接口

时间:2012-01-24 00:47:58

标签: java hibernate persistence

我正在尝试设置一个简单的联系人应用程序PersonCompany派生自名为Atom的基类:

Atom
  +-Contact
      +-Person
      +-Company
  +-ContactPhone
  +-ContactEmail

我想在上面添加ContactPhoneContactEmail。我想要做的棘手的操作是合并两个人并自动合并他们相应的电子邮件和电话。假设我们将这两个人称为胜利者和宽松者,我希望进行以下更新:

update ContactPhone CP set CP.contact_id=winnerid where CP.contact_id=looserid
update ContactEmail CE set CE.contact_id=winnerid where CE.contact_id=looserid

更进一步,我希望ContactPhoneContactEmail以及其他一些ClassConnectedToAContact来实现ConnectedToContact界面并执行以下查询:

update ConnectedToContact CTC set CTC.contact_id=winnerid where CTC.contact_id=looserid

让更新在符合条件的所有联系人上运行并执行更新。到目前为止,我已经来到了这个不工作结构。也许你可以让我朝着正确的方向前进,让它发挥作用。也许它只需要一点点调整。

类Atom

为所有数据库元素提供唯一标识符。以及创建,更新,删除所有对象的状态

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Atom {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
...
}

课程联系

@MappedSuperclass
public abstract class Contact extends Atom {
    public abstract Collection<ContactPhone> getPhones();
    public abstract void setPhones(Collection<ContactPhone> phones);
    public abstract Collection<ContactEmail> getEmails();
    public abstract void setEmails(Collection<ContactEmail> emails);
    ...
}

班级人员

存储在自己的表中。

@Entity
public class Person extends Contact {
    ...
}

类公司

存储在自己的表中。

@Entity
public class Company extends Contact {
    ...
}

关键部分是我合并ContactPhoneContactEmailContactConnected

接口ConnectedToContact

@MappedSuperclass
public interface ConnectedToContact {
    public Contact getContact();
    public void setContact(Contact contact);
}

类ContactPhone

@Entity
public class ContactPhone extends Atom implements ConnectedToContact {
...
}

类ContactEmail

@Entity
public class ContactEmail extends Atom implements ConnectedToContact {
...
}

1 个答案:

答案 0 :(得分:0)

我会在类似

的代码中实现它
public void Merge(Contact contact1, Contact contact2)
{
    session.beginTransaction();
    Contact winner = null;
    Contact loser = null;
    // determine winner and loser

    // Hibernate should know which entities implements ConnectedToContact
    List<ConnectedToContact> loserData = session.createCriteria(ConnectedToContact.class)
        .add(Restrictions.eq("Contact.Id", loser.getId()))
        .list();

    for(ConnectedToContact item : loserData)
    {
        item.setContact(winner);
    }
    session.getTransaction().commit();
}