关于java:将JPA应用程序适配到另一个数据库时可用的选项

Options avaiable when adapting JPA application to another database

我对JPA还是很陌生,并且正遇到JPA应用程序的问题。

我正在处理一个使用BaseEntity概念映射到其当前数据库的应用程序,其中所有实体都对此进行了扩展。此BaseEntity的" id"列映射如下:

1
2
3
4
5
6
7
8
9
10
11
/**
 * Getter for the id.
 *
 * @return id Represents the primary key column of the record.
 */

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name ="id",nullable = false)
public Long getId() {
    return id;
}

所有实体都对此进行了扩展,并且可以在其当前数据库中正常运行。

现在我的任务是使该应用程序适应使用类似的另一个数据库开始的工作,但是主要区别在于,在另一个数据库上,所有表的主键都被命名为" table_name _"," id",这不适用于我当前的映射。更改数据库列不是我的选择,我只能控制应用程序代码。

我在这里有什么选择?最好的做法是什么?我考虑过以某种方式在运行时获取类名并将其附加到列中。那会是个好主意吗?我正在使用hibernate方式。

谢谢您的时间。


您可以为其他数据库使用特定的映射文件。

但是只要没有其他以_id结尾的列,对当前数据库使用自定义的NamingStrategy可能会更容易。

添加与其他数据库匹配的ID:

1
2
3
4
5
6
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name ="my_table_id")
public Long getId() {
    return id;
}

对于当前数据库,您扩展DefaultNamingStrategy

1
2
3
4
5
6
7
8
9
public class CurrentDatabaseNamingStrategy extends DefaultNamingStrategy {

    public String columnName(String columnName) {
      if (propertyName.endsWith("_id")) {
        return"id";
      }
    }

}

现在您可以在persistence.xml

中为当前数据库定义一个

1
2
3
4
5
<persistence-unit...>
  <properties>
    <property name="hibernate.ejb.naming_strategy" value="CurrentDatabaseNamingStrategy" />
  </properties>
</persistence-unit>

不幸的是,NamingStrategy没有将实体类或表名称作为参数-因此,使用该解决方案,您将无法坚持旧的Column注释。


只需使用以下注释您的实体类:

1
2
3
@AttributeOverrides({
    @AttributeOverride(name="id", column=@Column(name="table_name_id")),
})