【问题标题】:saving entities with many to one relationships保存具有多对一关系的实体
【发布时间】:2015-10-12 10:03:49
【问题描述】:

我有以下实体

@Entity
public class Session{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;
    @OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, orphanRemoval=true)
    @JoinColumn(name="session_id", referencedColumnName="id")
    private List<SessionChart> sessionCharts;

    public List<SessionChart> getSessionCharts() {
        return sessionCharts;
    }

    public void setSessionCharts(List<SessionChart> sessionCharts) {
        this.sessionCharts = sessionCharts;
    }
}

和一个实体

@Entity
@Table(name="session_chart")
public class SessionChart implements  {



    @Transient
    private boolean isActive = false;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String chartName;
}

假设我已从特定会话中检索到我的会话图表

List<SessionChart> mySessionCharts = new ArrayList<SessionChart>();
mySessionCharts = session.getSessionCharts();

在我的代码中,我更改了一个sessionChart 的名称。如果我保存会话(合并)实体,那么 sessionCharts ArrayList 将被更新。我的问题如下:

我可以只保存列表中的SessionChart 对象而不保存会话吗?如果我删除会话图表并将其从 ArrayList 中删除,它会起作用吗?

我正在使用 jpa hibernate 和 EntityManager 和 EntityManagerFactory 进行数据库事务。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    我可以只保存列表中的 SessionChart 对象而不保存会话吗?

    是的,只要实体仍然受到管理并且您的交易仍然有效,这是可能的。所以这段代码可以工作:

    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();
    Session session = em.find(Session.class, 1);
    List<SessionChart> mySessionCharts = session.getSessionCharts();
    for (SessionChart sessionChart : mySessionCharts) {
        sessionChart.setChartName("test"); // this will update each session chart name in the DB
    }
    em.getTransaction().commit();
    em.close();
    

    如果我删除一个会话图表并将其从 ArrayList 中删除,它会起作用吗?

    我不确定我是否理解您的问题,但问题是:如果您只是从集合对象中删除 SessionChart 对象,然后调用 em.merge(session),这将取消链接 SessionChart 对象来自其父 Session。下面的例子:

    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();
    Session session = em.find(Session.class, 1);
    List<SessionChart> sessionChartList = session.getSessionCharts();
    sessionChartList.remove(0); // remove the first object from the list
    em.merge(session);
    em.getTransaction().commit();
    

    这将导致 session_chart 表上的 SQL 更新:

    update
        session_chart 
    set
        session_id=null 
    where
        session_id=1
        and id=1
    

    您仍然必须调用 em.remove(sessionChart) 才能将其从数据库中显式删除。

    【讨论】:

    • 我在想如果我可以做 em.remove(sessionChart) 并且这也会更新会话实体。但我想它没有
    • 如果您调用 em.remove(sessionChart),则不会更新内存中的集合对象。因此,如果您从列表中迭代 sessionChart 对象,您仍然可以引用从数据库中删除的对象,因为该对象保留在内存中。但是,如果您尝试通过 em.find() 或任何查询再次从数据库加载会话对象,您将获得 sessionChart 对象的更新列表。
    猜你喜欢
    • 1970-01-01
    • 2019-04-24
    • 2021-03-08
    • 2021-03-27
    • 2012-03-04
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多