将域模型映射到旧数据库

时间:2013-08-09 10:52:44

标签: hibernate

首先,我需要说我不是Hibernate的专家。我只在其他项目中使用过它的基础知识。但是现在,我想在遗留数据库方案上使用Hibernate,但是我在将表映射到Java域模型时遇到了一些困难:

1)许多表具有由用户分配的主键(作为字符串)。所以它们不是根据某种算法生成的。事实上,它们是Hibernate所谓的“自然”键。 有没有办法告诉Hibernate接受用户分配的ID?

2)第二个问题是很多表都有一些共同的属性,如:valid_from,valid_to,date_created,date_last_modified,user_last_modified& user_created。 这些属性用于审核(哪个记录由哪个用户更改),并在'valid_to'日期字段过去时禁用记录。我不想将这些字段暴露给最终用户,因为它们似乎是“元数据”,但我必须找到一种方法来更新这些字段。在Hibernate中是否有一个通用的解决方案,每当记录被更改时我都可以使用它来更新这些字段?有关信息,这些字段也用于“链接表”,用于管理2个表之间的多对多关系。

非常感谢所有帮助!

更新: 我将使用AbstractEntity来保存公共属性并使用EventListener来插入/更新这些字段。 UserContext.getCurrentUser()将检索用户(用户将使用ThreadLocal绑定到当前线程)。

现在唯一的问题是如何处理那些'关联'表...它们还包含那些公共字段,我不想创建一个单独的类来映射这样的关联表。在我看来,Hibernate在隐藏这样的链接表方面做得很好。我有办法用EventListener更新这样的链接表吗?

例如:如果表A通过链接表A_B与B类具有多对多关系,那么只要在A或B上插入/更新记录,就有办法更新A_B吗?

1 个答案:

答案 0 :(得分:1)

我想您使用JPA注释来声明您的映射。

第一个问题。只是不要应用@GeneratedValue注释。

public class SomeEntityWithAutogeneratedId {
    @Id
    @GeneratedValue // autogeneration
    private Long id;
}

public class SomeEntityWithoutAutogeneratedId {
    @Id
    private String id;
}

第二个问题。您可以准备一个基类来简化公共字段的映射。然后,您可以使用@PrePersist在更新前为所有必填字段应用正确的值:

public abstract class AbstractEntity {

    @Column
    private Date dateLastModified;

    @PrePersist
    public void beforePersist() {
        this.dateLastModified = new Date();
    }
}

public class Entity1 extends AbstractEntity {
public class Entity2 extends AbstractEntity {
public class Entity3 extends AbstractEntity {
...
public class EntityN extends AbstractEntity {

通常,如果您想通过Hibernate使用遗留数据库,最好在开始编写代码之前查看表结构/关系并进行适当的更改。这可以为您节省大量时间。例如,最好:

  • 使用自动生成的唯一标识符替换复合键(有关说明,请参阅this entry from the official documentation
  • 通过hibernate功能或java代码删除/替换所有触发器或存储过程。如果您的所有逻辑都在应用程序代码中,那么将很容易使用缓存功能。
  • 我现在无法想象别的东西,但你可以拥有一个很长的列表,因为SQL数据库为你提供了更多的功能/物品,这些功能/物品不能通过Hibernate轻松使用