Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/42.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 Hibernate和无限循环-重复条目_Java_Spring_Hibernate_Jpa_Transactions - Fatal编程技术网

Java Hibernate和无限循环-重复条目

Java Hibernate和无限循环-重复条目,java,spring,hibernate,jpa,transactions,Java,Spring,Hibernate,Jpa,Transactions,我遇到了一些与工作相关的问题: 有一个业务需求是通过多播主动接收数据报数据包,在本例中,这意味着我们使用while-true循环 伪代码如下所示: while (true) { receivePacket(); parsePacket(); saveParsedPacketToDatabase(); } 我们使用Spring Data JPA将实体保存到数据库中-这是制作插入的组件: @Service @Transactional public class InsertServic

我遇到了一些与工作相关的问题:

有一个业务需求是通过多播主动接收数据报数据包,在本例中,这意味着我们使用while-true循环

伪代码如下所示:

while (true) {
  receivePacket();
  parsePacket();
  saveParsedPacketToDatabase();
}
我们使用Spring Data JPA将实体保存到数据库中-这是制作插入的组件:

@Service
@Transactional
public class InsertService {

    @Inject
    private DataRepository dataRepository;

    @Transactional(propagation = Propagation.NEVER)
    public void saveParsedPacketToDatabase(List<Data> data) {
        dataRepository.save(data);
        dataRepository.flush();
    }
}
现在的问题是,我们得到了两个相同的对象,所有字段都是相同的,但insertTime和生成的id是相同的。重要的是,insertTime的差异是毫秒,每个插入的实体不超过100

我一直在试着调试这个东西,并找出问题所在,但我没有任何线索。。我们肯定不会通过多播获得重复数据,我认为插入技术可能有问题。。跳过无限循环不是一个选项-也许需要以某种方式排队

我非常感谢你的帮助

干杯,
马辛

今年早些时候,我面临着与此类似的问题。首先,摆脱你的整个preSave方法@PreUpdate和@PrePersist都是垃圾,Hibernate4不应该支持它们,它们会给你带来比你想象的更多的麻烦。我知道这一点,因为这是我试图解决这个问题时采取的原始路线

我假设您使用的是MySQL数据库或类似数据库,但任何像样的RDBMS都应该能够处理我的建议

要解决此问题,您需要使用@Generatedvalue=GenerationTime.ALWAYS注释insertTime字段。这基本上是对数据库说“无论何时插入此记录,都要为此字段生成一个值”

在数据库中,可以为表示insertTime的列指定默认值,该列表示当前时间。大多数RDBMS都支持这样的东西,我对这样一个字段的HSQL表声明现在是dateModified TIMESTAMP DEFAULT,但您可能需要根据您使用的数据库类型进行检查。无论何时将insertTime值插入数据库,都应该设置该值。作为预防措施,如果@Generated字段有一个值,我只需将它们设置为null,以确保没有任何内容进入,并且输出的任何值都必须由数据库设置


如果这不起作用或者您需要更多的解释,请告诉我。

我已经玩了一段时间,通过调试hibernate插件,我意识到我没有说这里的重要部分:我一直在使用Spring的ApplicationEventPublisher接口发布业务事件

整个过程介于receivePacket和parsePacket方法之间

我意识到ApplicationEventPublisher的publishEvent方法正在进行数据库插入-我还不确定它为什么要这样做-我猜在Spring的数据代码中有一些东西在听-我会在有更多时间的时候尝试本地化源代码-现在我很高兴它能工作

对不起,没有提供相关信息;我希望将来有人会利用这些信息

最好的,
Marcin

什么是应用程序服务器。是否有重试逻辑。有时,如果某些事务在服务器级别失败,application server admin会配置重试逻辑。我们使用的Apache Tomcat几乎都是默认配置。我确实删除了导致字段为空的注释,但这只是测试-我们仍然会为每个插入的行获取两个条目
@PreUpdate
@PrePersist
void preSave() {
    insertTime = DateTime.now(DateTimeZone.UTC).toDate();
}