JPA以事务一致的方式刷新逆字段

时间:2012-01-27 21:04:26

标签: jpa-2.0

这已经困扰了我多年,但我在jpa参考资料或本网站上找不到任何关于它的信息。当一个实体有一个计算成员(反向通过mappedby,@ Formula,......)时,似乎没有任何方法可以获得该计算成员的事务一致性更新。模式似乎是一方的制定者需要知道消费者并在原地更新它们。我肯定错过了什么。希望以下内容足够说明。

我不介意,如果要求是我必须在obj w /计算成员上再次调用em.getReference或.find,以防原始fetch中的那些不同步,但是只返回完全相同的实例w /没有字段更新。

import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PersistenceContext;

import org.springframework.transaction.annotation.Transactional;

@Entity
public class InverseProblemDto {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @OneToMany(mappedBy="problem")
    public Set<OwnerDto> owners;

    public int otherField = 0;
}

@Entity
public class OwnerDto {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @ManyToOne
    public InverseProblemDto problem; 

    public int yetAnotherField = 0;
}


@Transactional
public void wontWork(int dbId) {
    @PersistenceContext
    EntityManager em;

    InverseProblemDto probDto = em.find(InverseProblemDto.class, dbId);
    probDto.otherField++;

    for (OwnerDto other : probDto.owners) {
        // do something
    }

    OwnerDto newOwner = new OwnerDto();
    newOwner.problem = probDto;
    em.persist(newOwner);

    // do more

    // How to ensure this finds newOwner w/o breaking transactional integrity by forcing a flush and refresh???
    for (OwnerDto other : probDto.owners) {
        if (other.id == newOwner.id) System.out.println("Yeah! found it");
    }

}

1 个答案:

答案 0 :(得分:1)

刷新和刷新不提交事务,只是将挂起的sql发布到数据库。

您可以像这样自己更改值:

@Entity
public class InverseProblemDto {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @OneToMany(mappedBy="problem")
    public Set<OwnerDto> owners;

    public int otherField = 0;

    public void addOwner(OwnerDto owner) {
        ...
    }
}

@Entity
    public class OwnerDto {
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @ManyToOne
    public InverseProblemDto problem; 

    public int yetAnotherField = 0;

    public void setProblem(InverseProblemDto problem) {
        if(problem != null) {
            problem.addOwners(this);
        }
        this.problem = problem;
    }

}