Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否在运行时更改实体的表名?_Java_Hibernate_Orm_Jpa_Jpa 2.0 - Fatal编程技术网

Java 是否在运行时更改实体的表名?

Java 是否在运行时更改实体的表名?,java,hibernate,orm,jpa,jpa-2.0,Java,Hibernate,Orm,Jpa,Jpa 2.0,该表每月生成一次。所有月表的表结构基本相同 因为映射同一个实体只是使用不同的表名需要大量的工作 是否可以在运行时更改实体的表名,如下所示,因为它们毕竟具有相同的表结构 @Entity @Table(name="FOO_JAN2010") // any other ways to generate this dynamically? public class FooJan2010Table { // if we can dynamically set the table nam

该表每月生成一次。所有月表的表结构基本相同

因为映射同一个实体只是使用不同的表名需要大量的工作

是否可以在运行时更改实体的表名,如下所示,因为它们毕竟具有相同的表结构

   @Entity
   @Table(name="FOO_JAN2010") // any other ways to generate this dynamically?
   public class FooJan2010Table {  // if we can dynamically set the table name this can be simply named FooTable
       ...
   }

如果没有,你能建议什么方法?

我想不出一个好的方法来描述这一点。如果这是一个遗留数据库,您将很难使用JPA访问它

但是,如果数据库布局在您的控制之下,那么我会更改它。拥有多个布局完全相同的表通常是糟糕的设计。如果只有一个表包含年和月的额外列,则可以获得相同的结果。别忘了在这两列上加一个索引

是否可以在运行时更改实体的表名,如下所示,因为它们毕竟具有相同的表结构

   @Entity
   @Table(name="FOO_JAN2010") // any other ways to generate this dynamically?
   public class FooJan2010Table {  // if we can dynamically set the table name this can be simply named FooTable
       ...
   }
这实际上是不可能的,至少对于标准JPA(这并不意味着我使用非标准JPA)是不可能的,如以下问题所述:

总之,JPA没有提供一种方法来“改变”已经初始化的持久化单元的给定实体(以及相关的预编译CRUD查询、预编译命名查询等)

尽管如此,由于您使用的是Hibernate,也许可以看一看,了解一下使用Hibernate核心API可以做些什么

我能想到的另一个选择是使用数据库同义词/别名:
FOO
将是
FOO\u JAN2010
的别名,直到。。。您可以将别名更改为指向2010年2月20日的
FOO_
。我从来没有测试过这个,我不知道它是否适合你的需要。但是这是另一个想法。

如果您使用Hibernate作为JPA提供程序,那么您可能可以使用它。请参阅以供参考

您应该能够设计命名策略,以动态方式返回表名

然而,你是否应该这样做的问题是完全不同的


另外,感谢Pascal提醒我,只有每个月重新创建一次EntityManagerFactory(有很多方法可以做到这一点,重新启动webapp是最简单的方法)

我也无法理解这一点,有类似的要求

由于我的表名相对很少(每天)更改,因此我最终在RDBMS(我正在使用DB2)为“活动”表定义了一个DB别名,并在@table注释中引用了表别名


我完全知道这不是OP严格要求的,但我想我会分享经验。

最初这是设计(有一年和一个月列),但我们发现这样做可以更有效地访问数据。如果需要的话,我们可能不得不返回到上一个实现。@Joopiter:Access的效率应该不会降低,如果您确保有有效的索引(在年和月列以及您在where子句中使用的任何其他索引上,按照与查询相关的顺序)。当表太大,索引无法放入数据库服务器的内存时,这种设计可能会变得效率低下。像这样的水平分区对于timeseries数据来说是完全标准的。一些数据库现在本地支持它;如果指定了日期范围,则可以从查询中删除整个表。谢谢,我们将为此创建一个同义词。@Joopiter:不客气。如果这能满足您的需求,它很可能是最佳选择。我不确定,但我认为命名策略不应该返回不断变化的内容。也许我想的太小了,但是CRUD查询,命名查询是在EntityManagerFactory创建时一次性计算和预编译的,我看不出动态命名策略有什么帮助。是的,我也这么想。有道理。但是,如果是每月一次,那么当然可以选择重新创建entitymanagerfactory或重新启动servlet上下文,我同意最后一部分(但我想确保我没有错过命名策略的一些明显内容)。这应该在注释部分。