Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.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_Mysql_Hibernate - Fatal编程技术网

Java Hibernate:从不同事务访问创建的实体

Java Hibernate:从不同事务访问创建的实体,java,mysql,hibernate,Java,Mysql,Hibernate,我有相当复杂的方法,它们在执行过程中创建并使用不同的实体。例如,我创建了一些图像,然后将它们添加到文章中: @Transactional public void createArticle() { List<Image> images = ... for (int i = 0; i < 10; i++) { // creating some new images, method annotated @Transactional images.ad

我有相当复杂的方法,它们在执行过程中创建并使用不同的实体。例如,我创建了一些图像,然后将它们添加到文章中:

@Transactional
public void createArticle() {
  List<Image> images = ...
  for (int i = 0; i < 10; i++) {
      // creating some new images, method annotated @Transactional
      images.add(repository.createImage(...));
  }

  Article article = getArticle();
  article.addImages(images);
  em.merge(article);
}
@Transactional
公共物品{
列表图像=。。。

对于(int i=0;i您可以尝试将数据源上的事务隔离设置为READ_UNCOMMITTED,但这可能会导致不一致,因此通常不建议这样做。

考虑利用Hibernate级联功能一次性持久化对象树,同时最小化数据库锁定:

@Entity
public class Article {
    @OneToMany(cascade=CascadeType.MERGE)
    private List<Images> images;
}

@Transactional
public void createArticle() {
    //images created as Java objects in memory, no DAOs called yet
    List<Image> images = ...  
    Article article = getArticle();
    article.addImages(images);
    // cascading will save the article AND the images
    em.merge(article);
}

我的最佳猜测是,您的事务隔离级别是可序列化的。这就是为什么DB会在整个事务期间锁定受影响的表。
如果是这种情况,请将级别更改为READ_COMMITTED.Hibernate(或任何JPA提供程序)可以很好地使用此版本。 除非您显式调用
entityManager.lock(someEntity,LockModeType.SomeLockType)),否则它不会锁定任何内容。


此外,当您选择事务边界时,首先考虑原子性是一个原子工作单元,它必须是事务性的,为了“优化”而将它分解成更小的事务是错误的。

我尝试使用这个,但是异常说它在Hibernate中是不允许的。无论如何,我不想读未提交的,我宁愿提交更改并使用它们。广告1:这是这可能是一个很好的解决方案,但我忘了提到一个事实,那就是在创建图像时,我需要知道它们的ID,这样才能将它们保存到磁盘上。我想除非我开始用哈希值保存它们,否则DB调用将是不可避免的。但是我仍然认为,如果对DB的所有调用都是分开的,那么它会起作用。广告2:我确实尝试过这个,但这是不可能的ads to
javax.persistence.EntityNotFoundException
就好像这两个事务彼此都不知道一样。尝试使用@SequenceGenerator在不阻塞的情况下生成映像Id。这将通过调用数据库序列来创建Id,但不会触发实体本身的插入tellyhttp://www.java2s.com/Tutorial/Java/0355__JPA/UseSequenceGenerator.htm。就像您拥有ID并且可以在提交图像插入之前使用它一样,您如何获得EntityNotFoundException?如果您可以发布stacktrace,但这意味着对一个ID在数据库中不再/尚未存在的实体调用了refresh、lock或getReference。您可以发布该ID的代码吗出现此错误的尝试,似乎没有提交第一个事务,因为调用方法本身是事务性的和非事务性的传播。我不知道如何进行,但现在它似乎正在工作。我将接受您的回答。(您可以在2小时内奖励您的赏金)
@Service
public class OtherBean {
    @Autowired
    private YourService yourService;    

    // note that no transactional annotation is used, this is intentional
    public otherMethod() {
        yourService.createImages(); // first transaction - images are committed

        yourService.addImagesToArticle(); // second transaction - images are added to article
    }
}