在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
DecompiledApkRepository:
@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注释,它的工作没有问题! 有任何想法吗? 你需要更多细节吗?
答案 0 :(得分:0)
虽然该方法已被标记为异步,但没有弹出事务标记,怀疑是导致问题。 尝试添加Spring事务:
org.springframework.transaction.annotation
@Transactional
希望这能解决问题。
答案 1 :(得分:0)
使用
ThreadLocals
保留Spring的事务上下文。这意味着您的SessionFactory仅可用于调度您的请求的线程,因此,如果您创建新线程,您将获得null和相应的异常。 您的@Async
方法的作用是使用TaskExecutor
在另一个线程中运行您的方法。因此,您的服务就会出现上述问题。
根据link