添加实体不会刷新父集合

时间:2012-09-05 14:23:23

标签: postgresql jpa jpa-2.0 eclipselink

问题和问题非常简单,虽然很烦人,我正在寻找全球解决方案,因为它是我们的应用程序范围的问题。

下面的代码真的不是很有趣,但我发布以便澄清!

我们使用带有JPA 2.0的PostgreSQL数据库,我们生成了所有的外观和实体,当然我们做了一些编辑,但实际上并不多。

问题是每个实体都包含其子集的集合,但是(仅限我们?)创建后不更新子元素。 对象被写入数据库,您可以轻松地选择它们,但我们真正希望看到的是父对象中刷新的子集合。

为什么会这样?如果我们(手动)刷新父em.refresh(parent)的实体,它就可以解决这个问题,但这对于我们在Facades中的大量工作我的意思。但也许别无他法?

感谢您的支持!

/ *编辑* /

我想它必须是一些注释问题或缓存或其他东西,但我已经尝试了

@OneToMany(mappedBy = "idquestion", orphanRemoval=true, fetch= FetchType.EAGER) 

@Cacheable(false)

无效。

/ *编辑* /

一些用于理解的示例代码。

数据库级别:

CREATE TABLE Question (
        idQuestion SERIAL,
        questionContent VARCHAR,    
    CONSTRAINT Question_idQuestion_PK PRIMARY KEY (idQuestion)
);

CREATE TABLE Answer (
        idAnswer SERIAL,
        answerContent VARCHAR,
        idQuestion INTEGER,
    CONSTRAINT Answer_idAnswer_PK PRIMARY KEY (idAnswer),
    CONSTRAINT Answer_idQuestion_FK FOREIGN KEY (idQuestion) REFERENCES Question(idQuestion)
);

我们在Netbeans 7.1中生成了一些实体,所有实体看起来都类似于:

@Entity
@Table(name = "question", catalog = "jobfairdb", schema = "public")
@XmlRootElement
@NamedQueries({ BLAH BLAH BLAH...})
public class Question implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name = "idquestion", nullable = false)
    private Integer idquestion;
    @Size(max = 2147483647)
    @Column(name = "questioncontent", length = 2147483647)
    private String questioncontent;
    @OneToMany(mappedBy = "idquestion", orphanRemoval=true) 
    private Collection<Answer> answerCollection;

Getters... setters...

我们使用(再次)为它们生成外观,所有实现AbstractFacade如:

public abstract class CCAbstractFacade<T> {
    private Class<T> entityClass;

    public CCAbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

2 个答案:

答案 0 :(得分:1)

如果您在事务完成后使用container managed transactions 获取集合,则会自动更新父实体。否则,您必须自己更新集合。

本文详细解释了这种行为:JPA implementation patterns: Bidirectional associations

编辑:

使用容器管理事务的最简单方法是在transaction-type="JTA"中使用persistence.xml并使用Container-Managed Entity Managers

答案 1 :(得分:0)

您似乎设置了ManyToOne方面,但没有添加到OneToMany,您必须同时执行这两项操作。

在JPA和Java中,您必须更新双向关系的两面,否则对象的状态将不会同步。不这样做,在任何Java代码中都会出错,而不仅仅是JPA。

JPA中没有任何魔法会为你做这件事。 EclipseLink确实有一个神奇的选项,您可以通过自定义程序(mapping.setRelationshipPartnerAttributeName())进行设置,但不建议这样做,修复您的代码是正确的最佳解决方案。

请参阅, http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Object_corruption.2C_one_side_of_the_relationship_is_not_updated_after_updating_the_other_side