【问题标题】:jpa repository save method returns different id from the one inserted into databasejpa 存储库保存方法返回与插入数据库的 ID 不同的 ID
【发布时间】:2014-05-24 17:32:19
【问题描述】:

我正在使用 Spring Data (jpaRepository) + Oracle 11g 数据库。

这是我的 JUnit 测试代码:

@Test
    public void testAjoutUtilisateur() {
    Utilisateur utilisateur = new Utilisateur();

(...)

    utilisateur=repository.save(utilisateur);

    Utilisateur dbutilisateur = repository.findOne(utilisateur.getIdutilisateur());
    assertNotNull(dbutilisateur);

当我调试时,我发现repository.save 方法返回的“utilisateur”对象的 id 类似于“2100”,而数据库中相应插入的行的 id 类似于“43 ”。

我有一个带有序列和触发器的 Oracle 数据库,以便为我的“Utilisateur”表的 id 设置自动递增属性。

这是我的 Utilisateur 实体中的 id 定义:

@Entity
@NamedQuery(name="Utilisateur.findAll", query="SELECT u FROM Utilisateur u")
@SequenceGenerator(sequenceName="ID_UTILISATEUR_SEQ", name="ID_UTILISATEUR_SEQ")
public class Utilisateur implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ID_UTILISATEUR_SEQ")
private Long idutilisateur;

问题出在哪里?是否在 save 方法中?

谢谢。


编辑:

我发现问题已经被@jhadesdev的解决方案解决了,并且我正在谈论的数据线是在触发器处于活动状态时插入的。

最后,我不得不提一下,默认情况下,JUnit 测试似乎不会在数据库中插入数据(它先插入然后回滚)。为了使这种行为无效,我们必须在测试类中指定@TransactionConfiguration(defaultRollback=false) 注解。

例如(以我为例):

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:context/dao-context.xml" })
@TransactionConfiguration(defaultRollback=false)
@Transactional
public class UtilisateurRepositoryTest {

希望它可以帮助某人。

【问题讨论】:

    标签: eclipse spring oracle11g spring-data-jpa


    【解决方案1】:

    问题在于有两种不同的机制来生成密钥:

    • 在 Hibernate 级别调用序列并使用该值填充 Id 列并将其作为插入键发送到数据库
    • 还有一种 Hibernate 不知道的数据库机制:列通过触发器递增。

    Hibernate 认为插入是使用序列的值进行的,但在数据库中发生了其他事情。最简单的解决方案可能是移除触发机制,让 Hibernate 仅根据序列填充密钥。

    【讨论】:

    • 感谢@jhadesdev 的回复...我看到了问题,我会立即移除触发器并提供反馈
    • 但是为什么序列的值在 2000 左右?而我数据库中的序列现在的值在 50 左右?
    • 有人有想法吗?为什么我在数据库中找到 2100 或 3100 的 id,即使序列以 1 开头并以 1 递增??
    • 我终于发现问题是由于序列增加了 20 !我不知道它是如何设置为 20 的,但是当我检查时,这就是我发现的。所以,我删除了这个序列并像这样重新创建它:CREATE SEQUENCE sequenceName START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
    • 这个答案已经结束了我数小时的头痛;-)。这篇文章对我也很有用:stackoverflow.com/a/8003294/2507819。它演示了如何在这种情况下保持触发器。
    猜你喜欢
    • 1970-01-01
    • 2021-04-23
    • 2018-06-08
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 2010-10-14
    相关资源
    最近更新 更多