如何在Hibernate中动态添加实体?

时间:2015-11-25 08:18:41

标签: java hibernate spring-mvc datapersistance

我是一名java开发人员。我正在使用spring 4.0.1hibernate 4.2.21。我有一个课程如下:

@Entity
@Inheritance(...)
public abstract class Feature{
   @Id
   @GeneratedValue
   protected Long id;

   ...

}

现在我有很多课程如下:

Label.java类:

@Entity
public class Label extends Feature{
   protected String str;

   ...
}

Point.java类:

@Entity
public class Point extends Feature{
   protected Integer intg;

   ...
}

我有超过20个从Feature类扩展的Entity类。有没有办法在不编写硬编码的情况下动态地将这些类(例如LabelPoint)添加到项目中?

更新

例如,Hibernate从数据库中获取数据,然后根据这些数据创建模型。

  1. 有可能吗?
  2. 我该怎么办?

7 个答案:

答案 0 :(得分:6)

我认为它不是一个需要动态更改的好数据库设计。这听起来冗长而且不一致。再次观察您的域并尝试设计一个不会在运行时更改的正确实体关系。

答案 1 :(得分:6)

您可以尝试收集所需的数据来构建模型并为每个实体生成一个hibernate hbm.xml文件(xml格式,并且在阅读更新中描述的所需数据后很容易用java生成)

之后,您可以按照http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html#configuration-programmatic

以编程方式创建一个hibernate配置对象

我认为,如果我理解你的问题,你可以达到你想要的目标。

答案 2 :(得分:5)

我认为你想在运行时生成你的实体类,而不是你必须编写你的java文件并编译它等等。 如果这是您的要求,您可以使用字节码生成器(如 javassist )在运行时生成和注释您的类文件。然后,您可以使用JPA,Hibernate和任何其他ORM框架将其持久化到您的表中。我正在写一个基于xml文件的类生成器。在未来几天它将完成,我将给你一个链接到我的github。因此,您可以使用它来生成实体类。祝你有愉快的一天:)

答案 3 :(得分:3)

据我了解,您需要开发一个工具,收集与Feature表具有一对一关系的表名。

我的建议是这样的(用Oracle测试):

1)从您的数据库中获取正在重新设置Feature表的表元数据。 下面将打印与您的表具有外键关系的Label,Point等表。
如果您只想生成一个子集(不相关的表也可能有这种关系)可能是您放置 common < / strong>外键列名称,并借助此类标记过滤掉不相关的表。

Connection connection = jdbcTemplate.getDataSource().getConnection();
DatabaseMetaData metaData = connection.getMetaData();

ResultSet exportedKeys = metaData.getExportedKeys(connection.getCatalog(), "<your_schema_name>", "FEATURE");
while (exportedKeys.next()){
    String fkTableName = exportedKeys.getString("FKTABLE_NAME");
    String fkColumnName = exportedKeys.getString("FKCOLUMN_NAME");  
    System.out.println("[fkTableName:" + fkTableName + "], [fkColumnName" + fkColumnName + "]");
}
exportedKeys.close();


2)对于您上面收集的表,对于我们关注的每个表,获取类型和列的表元数据。

ResultSet columns = metaData.getColumns(connection.getCatalog(), "<your_schema_name>", "<your_table_name>", null);
while (columns.next()){
    String columnName = columns.getString("COLUMN_NAME");
    String typeName = columns.getString("TYPE_NAME");
    System.out.println("[columnName:" + columnName + "], [typeName" + typeName + "]");
}
columns.close();


3)根据2的结果生成你的Java类。使用字段,getter setter,annotations等。然后将它们复制到源目录中。你知道其余的人了。

希望这有用。

答案 4 :(得分:2)

我认为您可以使用Hibernate Reverse Engineering为所有数据库表生成实体。请参阅this链接。这将解释使用hibernate逆向工程从数据库生成实体的逐步过程。

答案 5 :(得分:2)

不要重复自己。

如果你真的需要这些类,可以使用IDE(比如eclipse)来生成类。或者使用泛型和继承来创建一个能够存储字符串和整数的类。

但是如果你实际上不需要类,则生成SQL(不是JPQL或HQL)并将数据存储在java.util.Map和类似的数据结构中。

课程适用于:

  • 类型安全
  • 将逻辑(方法)与数据(字段)相结合
  • 描述关系

在您的情况下,您可能只需要:

  • 在运行时存储结构化数据。

答案 6 :(得分:1)

我认为你可以用eclipse做到这一点,但是必须或多或少地修改类以保留继承层次结构。

  • 右键单击项目名称,然后选择属性
  • 如果未启用项目构面,则使用项目构面

enter image description here

  • 如果未选中,请点击 JPA ,然后点击确定关闭项目属性窗口。

  • 在项目属性中启用JPA后,现在再次右键单击您的项目名称,您会看到一个新的上下文菜单项 JPA tools 。选择从表格生成实体

enter image description here

选择一个数据库连接,让Eclipse获取用于生成的表 来自。

这是how to setup db in eclipse

  • 最好使用上述方法在虚拟项目中创建实体,并将实体类复制到实际项目中。

  • Eclipse的类重构可用于保留所需的继承层次结构。

希望这有帮助。