JPA实体中的前/后加载更新

时间:2014-12-04 11:50:28

标签: java spring hibernate jpa orm

我在Spring Data JPA和Hibernate中有项目。

有两个JPA实体 - 用户和工作。每个用户都有多个作业。每个作业都有字段状态。创建新作业时,会向远程服务器发送新请求,并以状态IN PROGRESS保存作业。

可以使用它的ID从远程服务器查询更新的状态。请求的业务逻辑应该始终返回存储的状态,但是当作业处于IN PROGRESS状态时,应该查询远程服务器的更新状态,该状态应该在之后存储。

应该解释我的意图的伪代码:

@Entity
class User {
    private long id;
    private String username;
    private Collection<Jobs> jobs;
}

@Entity
class Job {
    private long id;
    private User user;
    private Status status;
    @Inject
    private JobRepository jobRepository;

    @PrePersist
    private setDefaultStatus() {
        status = IN_PROGESS;
    }

    @PostLoad
    private checkUpdatedStatus() {
        if (this.status == IN_PROGESS) {
            this.status = askRemoteServerForJobStatus(this.id);
            jobRepository.save(this);
        }
    }
}

伪代码用法:

userRepsitory.find(1).jobs // should trigger checkUpdatedStatus
jobsRepository.findAll() // should trigger checkUpdatedStatus

我认为在Job实体中包含jobRepository依赖项是一个好习惯(如伪代码所示),所以我当前的实现在存储库中完成所有这些 - 我有findAll()这样的方法这将调用PostLoad / checkUpdatedStatus类方法。但是我也从所有其他存储库中调用它,例如User repository,它也可以获取Job项。

在我看来,这是一个非常合理的用例,所以我不相信,没有更好的方法可以做到这一点。有没有人做过类似的事情?如果你能让我走上正轨,我会非常高兴。

谢谢你, vlastikcz

2 个答案:

答案 0 :(得分:2)

将存储库注入实体并不是一个好的举措。实体是持久化结构,存储库应该管理实体而不是相反。考虑事务划分和瞬态/分离实例。

添加实体时,有一种更好的方法可以调用某个登录。您可以使用电子邮件vent listener for this。您配置一个也是Spring bean的加载侦听器,因此您可以在此侦听器中注入其他服务/存储库。

答案 1 :(得分:0)

最后,@ Alan的评论让我再次思考,我提出了不同的方法。

创建作业后,我启动一个异步任务,只需轮询远程服务器,直到收到结果。

像这样:

@HandleAfterCreate
public void addNewRemoteJob(Job job) {
    remoteJobDispatcher.sendRequest(job);
    remoteJobDispatcher.waitForTheResult(job);
}

class RemoteJobDispatcher {
    @Async
    public void waitForTheResult(Job job) {
        while(true) {
            status = askRemoteServerForJobStatus(job)
            if (status != IN_PROGRESS) {
                job.setStatus(status);
                jobRepository.save(job);
                return;
            }
            sleep(2000);
        }
    }
}

可能有类似的计划或启动作业,以处理可能的意外应用程序状态,但没关系。

谢谢!