当前位置: 首页 > 知识库问答 >
问题:

将@ElementCollection移动到@Embeddeble类不起作用

郑正文
2023-03-14

我试图将@ElementCollection注释字段从我的@Entity类移动到另一个我用@embeddeble注释的类中。当字段位于实体中时,Hibernate将发出正确的INSERT语句。将字段移动到@embeddeble类时,不会生成INSERT语句。

所以这工作:

@Entity
public class MyEntity extends AbstractEntity<MyEntityId> {
  @ElementCollection
  @OrderColumn
  private List<Double> doubles;
}

但这并没有:

@Entity
public class MyEntity extends AbstractEntity<MyEntityId> {
  @Embedded
  private Doubles doubles;
}

@Embeddable
public class Doubles {
  @ElementCollection
  @OrderColumn
  private List<Double> doubles;
}

保存MyEntity实例(并刷新EntityManager)时,没有例外。如果我禁用在Flyway中创建适当的表,Hibernate验证会触发“缺少表[my_entity_doubles]”错误,因此Hibernate似乎可以正确解释设置。

使用Spring Boot 2.3.4,使用HiberNate 5.4.21。

更新:https://github.com/wimdeblauwe/so-64336648有一个可复制的测试用例

共有1个答案

袁晋鹏
2023-03-14

正如JPA规范中所述(参见2.5可嵌入类部分):

可嵌入类(包括另一个可嵌入类中的可嵌入类)可能包含基本类型或其他可嵌入类的集合。可嵌入类之间不允许直接或间接循环包含依赖关系。

还有一个简单的例子(基于Hibernate 5.4.21)。

假设我们有以下模式:

sql prettyprint-override">create table T1_MY_ENTITY
(
   tm_id int not null,

   primary key (tm_id)
);

insert into T1_MY_ENTITY values (1);

create table T1_MY_COLL
(
   tc_tm_id int not null,
   tc_ord_id int not null,
   tc_code varchar(100),

   foreign key (tc_tm_id) references T1_MY_ENTITY(tm_id)
);

insert into T1_MY_COLL values (1, 1, 'CL1'), (1, 0, 'CL2');

以及以下映射:

@Entity
@Table(name = "T1_MY_ENTITY")
public class MyEntity
{
   @Id
   @Column(name = "tm_id")
   private Long id;

   @Embedded
   private Doubles dou;
   
   // constructor, getters, setters
}

@Embeddable
public class Doubles
{
   @OrderColumn(name = "tc_ord_id")
   @ElementCollection
   @CollectionTable(name = "T1_MY_COLL", joinColumns = @JoinColumn(name = "tc_tm_id"))
   @Column(name = "tc_code")
   private List<String> colls;

   // constructor, getters, setters
}

以下代码:

MyEntity myEntity =  entityManager.find(MyEntity.class, 1L);
myEntity.getDou().getColls().add("CL5");
entityManager.merge(myEntity);

将生成插入:

19:51:29,612 DEBUG SQL:128 - 
    /* insert collection
        row com.my.hibernate.entities.MyEntity.dou.colls */ insert 
        into
            TEST_SCHEMA.T1_MY_COLL
            (tc_tm_id, tc_ord_id, tc_code) 
        values
            (?, ?, ?)
Hibernate: 
    /* insert collection
        row com.my.hibernate.entities.MyEntity.dou.colls */ insert 
        into
            TEST_SCHEMA.T1_MY_COLL
            (tc_tm_id, tc_ord_id, tc_code) 
        values
            (?, ?, ?)
19:51:29,612 TRACE ResourceRegistryStandardImpl:83 - Registering statement [/* insert collection row com.my.hibernate.entities.MyEntity.dou.colls */ insert into TEST_SCHEMA.T1_MY_COLL (tc_tm_id, tc_ord_id, tc_code) values (?, ?, ?)]
19:51:29,612 TRACE BasicBinder:64 - binding parameter [1] as [BIGINT] - [1]
19:51:29,613 TRACE BasicBinder:64 - binding parameter [2] as [INTEGER] - [2]
19:51:29,613 TRACE BasicBinder:64 - binding parameter [3] as [VARCHAR] - [CL5]

所以,看起来你的问题在于另一架飞机。

更新:对于您的测试用例,请尝试以下方式进行更正:

@Test
void test() {
   MyEntity2 entity = new MyEntity2();
   Doubles doubles = new Doubles();
   doubles.setDoubles(List.of(1.0, 1.5));

   entity.setDoubles(doubles); // It was absent !!!

   repository.save(entity);

   entityManager.flush();

   assertThat(jdbcTemplate.queryForObject("SELECT count(*) FROM my_entity2_doubles", Long.class)).isEqualTo(2);
}
 类似资料:
  • 我有一个问题的角色移动pyplay。我想做的是能够按住钥匙,让精灵移动。但是,我必须继续敲击键让精灵移动。任何帮助将不胜感激!这是我的代码: 谢谢

  • 问题内容: 在iPhone / iPad / iPod上的Webkit中,点击元素时不会触发为标签的:active伪类指定样式。我该如何触发?示例代码: 问题答案: … 仅应用了一次,而不是每个按钮元素都可以修复页面上的所有按钮。另外,您可以使用这个名为’Fastclick’的小型JS库。它可以加快触摸设备上的点击事件,也可以解决此问题。

  • 我正在运行一个嵌入式hazelcast部署,并存储一个,其中映射中的值类型是我的自定义类。 它的一个字段是接口。

  • 我正在使用Artisan::call('迁移');在Laravel控制器方法中,它在Laravel版本为4.1时工作。使用作曲家更新命令更新Laravel后(并在composer.js中设置laravel/框架:4.2.*),此控制器方法(因为这是其中唯一的命令)不再工作。 我甚至还加了“密码”= 这已经发生了:http://laravel.io/forum/06-02-2014-not-able

  • 在我的网页移动视图中,我可以垂直和水平滚动,但这总是从左上角开始。现在,我想使用window将视口设置为我的自定义位置。滚动到或类似的东西。窗滚动似乎只适用于桌面浏览器。 知道我怎么解决吗?

  • 我有一个注释驱动的Spring mvc 项目,在 JBoss 网络 mvc 示例之后模板化。(Spring,冬眠,JPA 2.0) 我有一个实用程序包,我想在其中为明显的实用程序函数放置可重用的类。具体来说,我有一个LogonU实用程序类,我想在其中查询数据库以获取信息。 我在那里自动连接我的DAO,但是当我调试时,DAO总是为空并且失败,有那个例外。 我已经阅读并尝试了很多东西——我知道我可能已