首页 \ 问答 \ EntityManager操作顺序(EntityManager operations order)

EntityManager操作顺序(EntityManager operations order)

我最近遇到了一个有趣的问题。 我在项目JPA + Hibernate + EJB中使用。 该问题涉及在同一事务中保存和删除实体。 使用的数据库表具有在两列上定义的唯一约束。

我所做的是删除实体调用

entityManager.remove();

然后,新实体在与唯一约束中使用的列关联的两个属性中添加相同的值,但在其他属性中使用不同的值:

entityManager.persist();

这两个操作在单个事务中执行,并按照上述顺序执行。 先移除,再加上第二。 然而,似乎在违反唯一约束时以颠倒的顺序执行操作。 看起来在删除前一个实体之前添加了新实体。

显然,我可以打电话

entityManager.flush()

删除后,然后不违反约束。 但是,在这种情况下,数据会在整个事务提交之前保存到数据库中。 这不是一个理想的行为。 如果在刷新之后出现任何问题,并且事务将被标记为回滚,则无论如何都将删除该实体。

我认为操作顺序与添加到事务中的操作顺序相同。 从我的例子可以看出事实并非如此。

删除后没有刷新或提交事务有没有办法解决问题?

谢谢。


I have run into interesting issue recently. I use in the project JPA + Hibernate + EJB. The issue concerns saving and deleting entities in the same transaction. Database table which is used has an unique constraint defined on two columns.

What I do is removing entity calling

entityManager.remove();

then the new entity is added with the same values in two properties associated with columns used in the unique constraint but different values in other properties using:

entityManager.persist();

Those two operations are carried out in a single transaction and are executed in the order as presented above. Removal first, addition second. However it seems that the operations are executed in the inverted order as unique constraint is violated. It looks like the new entity is added before removing the previous one.

Obviously, I can call

entityManager.flush()

after removal and then constraint is not violated. However in this case the data is saved to the database before the whole transaction commits. That is not a desirable behavior. If anything goes wrong after flush and transaction will be marked for rollback, the entity will be deleted anyway.

I thought that order of operations is the same as they were added to the transaction. From my example it turns out that it is not.

Is there any way to solve the issue without flushing or committing the transaction after delete?

Thank you.


原文:https://stackoverflow.com/questions/20284027
更新时间:2023-04-14 11:04

最满意答案

我终于明白了这里的实际行为。 这不是调用未定义的行为,而是定义您不想要的行为。

cin >> position;

这试图读取你的12位数字,它不适合int,所以读取失败。 因为格式错误失败,12位数字仍保留在缓冲区中,因此循环中的下一次传递尝试再次读取它。

当您打算读取键盘输入时,请始终使用cin::getline()cin的错误/清除逻辑不是为了重新同步键盘输入,而是为了重新同步从无法读取错误消息的生成器输入的输入。 将来,当您尝试将cin与管道一起使用时,最好的解决方案是检查cin::fail()并保存程序(如果它已设置)。


I finally understand the actual behavior here. This is not invoking undefined behavior but rather defined behavior you don't want.

cin >> position;

This tried to read your 12 digit number, which didn't fit into an int, so the read failed. Because it failed on a format error, the 12 digit number remained in the buffer, so the next pass around the loop tried to read it again.

Always use cin::getline() when you intend to read keyboard input. The error/cleanup logic in cin is not designed to resync keyboard input, but rather to resync input piped from a generator that can't read your error messages. In the future, when you try to use cin with a pipe, the best solution is to check cin::fail() and bail the program if it ever gets set.

相关问答

更多
  • 根据语言规范,迭代化学中的空条件等同于true条件。 6.5.3 for语句 1 for语句 for(for-init-statement condition opt ; expression opt )语句 相当于 { for-init-statement while ( condition ) { statement expression ; } } ... 2可以省略条件和表达式中的任何一个或两个。 缺失条件使隐含的while子句等同于while(true) 。 所以,循 ...
  • 我终于明白了这里的实际行为。 这不是调用未定义的行为,而是定义您不想要的行为。 cin >> position; 这试图读取你的12位数字,它不适合int,所以读取失败。 因为格式错误失败,12位数字仍保留在缓冲区中,因此循环中的下一次传递尝试再次读取它。 当您打算读取键盘输入时,请始终使用cin::getline() 。 cin的错误/清除逻辑不是为了重新同步键盘输入,而是为了重新同步从无法读取错误消息的生成器输入的输入。 将来,当您尝试将cin与管道一起使用时,最好的解决方案是检查cin::fail( ...
  • 正如其他答案所说,这是因为它没有签名和全部。 我会告诉你一个优雅的方式来做你想做的事情与一个无符号的整数。 unsigned int i=10; while(i --> 0) printf("Hello:%u\n", i+1); 这个-->有时被称为去运算符。 但事实上只是--和> 。 如果你改变间距,你会得到 while( i-- > 0 ) MY2C As other answers said, it's because it's unsigned and all. I will tell you ...
  • 这是部分答案。 我不明白这部分“......基于它是否是双重”PDRcount“或不是。” 这里是使用dplyr库的PDR!= 2的情况的部分答案。 在任何计算之前,我还通过在crossdata变量上使用dput简化了数据输入。 crossdata1<-structure(list(PDR = c(1, 2, 3, 4, 5, 2, 1, 2, 3, 4, 5, 2, 1, 2, 3, 4, 5, 2, 1, 2, 3, 4, 5, 2 ...
  • 也许是一个setjmp循环? 这很特别。 static jmp_buf buf; int i = 0; if ( setjmp(buf) < end ) { /* do stuff */ longjmp(buf, i++); } A setjmp loop perhaps? That is pretty special. static jmp_buf buf; int i = 0; if ( setjmp(buf) < end ) { /* do stuff */ l ...
  • 总是检查scanf()的返回值: int result; do { printf("How long is your shower(in minutes)?:"); result = scanf("%d", &minutes); if(result != 1) break; } while (minutes < 1); 较短的版本(如果只需要一次扫描): printf("How long is your shower(in minutes)?:"); while ...
  • 很难知道你的真实数据是什么样的,但是沿着这条线 full <- strptime(cloudFull[,1], '%d.%m.%Y %H:%M') ref <- strptime(clouds[,1], '%d.%m.%Y %H:%M') ## ref <- sort(ref) cloudsFull[, 2:3] <- clouds[findInterval(full, ref), 2:3] 使用findInterval()将问题转换为线性扩展而非二次扩展的问题。 Its hard to know wha ...
  • 夫妇的事情要注意。 你有用户输入一个字符的选择,所以让userChoice一个字符。 请注意,在这种情况下do-while如何用于输入验证。 我更改了额外的while循环,并在末尾使用了分号来表示条件语句。 您可以用开关“菜单驱动程序”替代if和ifs。 这是您想要的工作程序。 如果您希望在整个条件语句中使用do-while而不是将其用作输入验证,那么将其用于所有条件语句并检查,而不是C. #include #include using namespace std; ...
  • 当然我是盲目的,原因是在“while”之后错误的分号! 编译器认为没有循环体,只是重复执行“无”。 我读到的循环体,编译器只是认为是一个未命名的/匿名的范围,在循环之后,所以它永远不会被执行。 Of course I am blind, and the reason is the errant semicolon after the "while"! The compiler thinks there is no loop body, and just executes "nothing" repeated ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。