java - 使用存储库的异步方法中的 Spring InvalidDataAccessApiUsageException

标签 java spring hibernate spring-mvc asynchronous

在 RestController 中:

@RestController
@RequestMapping("/apks")
public class ApkController {
    @Inject
    DecompiledApkRepository decompiledApkRepository;

    @Autowired
    DecompileService decompileService;

    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<?> createFromJson(@RequestBody Apk apk) {
        ....
        DecompiledApk decompiledApk = new DecompiledApk(apk, apkFile, apk.getMd5Hash());
        decompileService.decompile(decompiledApk, apk.getMd5Hash(), decompiledApkRepository);

    } catch (IOException |InterruptedException e) {
        e.printStackTrace();
    }

    return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED);
}

DecompiledApk 实体:

@Entity
@Table(name = "decompiled_apks")
public class DecompiledApk {

    @Id
    @GeneratedValue
    @JsonIgnore
    private Long id;

    @MapsId
    @OneToOne(optional=false)
    private Apk apk;

    @Column(unique = true)
    private URI decompiledFolder;

    @Transient
    @JsonIgnore
    private File inputApk;

 // all public getters/setters, package empty constructor and public full constructor

反编译的Apk存储库:

@Repository
public interface DecompiledApkRepository extends CrudRepository<DecompiledApk, Long> {
    DecompiledApk findByApk_md5Hash(String md5Hash);
}

这里,问题出在 DecompileService 中的异步方法中:

@Service
public class DecompileService {
    private static final String DEC_FOLDER = "/tmp/decompiled/";


    @Async
    public Future<Void> decompile(DecompiledApk decompiledApk, String md5Hash, DecompiledApkRepository decompiledApkRepository) throws InterruptedException {
        /*
       ...
       */
        decompiledApk.setDecompiledFolder(URI.create(outputFolder));
        System.err.println("---start-->"+Thread.currentThread().getName());
        decompiledApkRepository.save(decompiledApk);
        System.err.println("---end-->"+Thread.currentThread().getName());
        return new AsyncResult<>(null);
    }

说明:

decompiledApkRepository.save(decompiledApk);

抛出:

org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.xxx.domain.Apk; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.xxx.domain.Apk

但是如果我删除 @Async 注释,它就可以正常工作! 有任何想法吗? 您需要更多详细信息吗?

最佳答案

虽然该方法已被标记为异步,但没有 spring 事务标记,怀疑是导致问题的原因。 尝试添加 Spring 事务:

org.springframework.transaction.annotation  


@Transactional

希望这能解决问题。

关于java - 使用存储库的异步方法中的 Spring InvalidDataAccessApiUsageException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35316535/

相关文章:

java - 刷新后看不到 Hibernate session 外的变化

hibernate - 如何避免使用 hibernate 模式更新

java - 忽略关系中的 FetchType.EAGER

java - Jpanel 未正确重绘

java - 无法替换字符串

java - 无法正确使用 Apache Camel requestBody

java - 带有 JPA : hibernate access without schema spécified in entity 的 Hibernate 5

java - 如何在 Android 的 Java 中以编程方式查找 "data"的路径?

spring - 从 Spring IO 下载/导入所有依赖项

java - spring ws配置wsdl生成策略?