EclipseLink persistence and refresh both associati

2019-08-01 13:10发布

I'm using EclipseLink in my Java EE project with a PostgreSQL database. I have trouble finding the right annotations for a correct behaviour when I persist/refresh entities which are part of oneToMany/manytoOne associations.

For example, I have an entity "Project" which is first created by the users through a UI. Then the users can add "Analysis" into the project they created. Hence, an analysis is part of one project and a project can have several analysis. The persist action works fine (I see a new analysis associated with the project in my database) but when I call "getProject(idProject)" and display the list of its analysis I don't get to see the refreshed list.

How should I do this ?

The current annotations are :

In Projet.java

   // bi-directional many-to-one association to Analyse
   @OneToMany(mappedBy = "projet", cascade = { CascadeType.ALL })
   private Set<Analyse> analyses;

In Analyse.java

  //bi-directional many-to-one association to Projet
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_projet", nullable=false)
private Projet projet;

The code to persist a new "analyse" :

public boolean insertAnalyse(Analyse analyse) {
    System.out.println("insertAnalyse");
    boolean success = true;
    fac = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
    em = fac.createEntityManager();

    try {
        em.getTransaction().begin();
        em.persist(analyse);
            em.getTransaction().commit();
    }

    catch (Exception ex) {
        em.getTransaction().rollback();
        System.out.println("*** Erreur in MeansDAO. insertAnalyse() : "
                + ex.getMessage());
        success = false;

    } finally {
        em.close();
    }

    return success;
}

The code to retrieve the current project by projectID :

   public Projet getProject(String p) {
    System.out.println("getProject");
    Projet project = null;

    fac = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
    em = fac.createEntityManager();

    try {
        em.getTransaction().begin();
        StringBuilder sql = new StringBuilder();

        Projet proj = em.find(Projet.class, Integer.parseInt(p));

        if (proj != null) {
            project = proj;
        }

    } catch (Exception ex) {
        em.getTransaction().rollback();
        System.out.println("*** Erreur in MeansDAO. getProject() : "
                + ex.getMessage());
    } finally {
        em.close();
    }

    return project;
}

Thanks in advance for your help!

1条回答
淡お忘
2楼-- · 2019-08-01 13:31

First of all, you should not need to refresh, if your code was correct. When you persist the analyse, if it is related to the project, then you should be setting the relationship both ways. My guess is you are not doing that. In JPA you are responsible for maintaining your relationships correctly.

See, http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Object_corruption.2C_one_side_of_the_relationship_is_not_updated_after_updating_the_other_side

The reason you are seeing the stale state of the relationship is (because you did not maintain both sides, but also) because EclipseLink maintains a shared cache by default. You can disable this,

See, http://wiki.eclipse.org/EclipseLink/FAQ/How_to_disable_the_shared_cache%3F

To refresh an object in JPA you need to call refresh() on it, or execute a Query or find() operation using the refresh query hint.

For more information on caching see, http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching

查看更多
登录 后发表回答