【问题标题】:Hibernate update non-reference fields of objectHibernate 更新对象的非引用字段
【发布时间】:2015-11-20 09:51:16
【问题描述】:

我想使用 Java、Spring Data/MVC/DI 和 Hibernate 开发一个 CMS,定义了类似 REST 的 API。

我有以下模型实体:

  • 有多个Articles
  • 每篇文章有多个Sections
  • 每个部分都可以有子部分和/或Item

所有这些实体都有自己的属性(例如名称、类型等),但很明显,它们指的是它们的聚合实体。我需要为每个这样的实体定义 CRUD API 方法。

我决定偏离教条式的 REST,当我进行修改时,我只需要传入特定于实体的属性(如名称、类型等),但不会影响聚合。因此我有这样的端点:

  • 发布/articles - 创建一篇文章,没有部分
  • put /articles/{article_id} - 更新基本文章属性,不影响部分
  • 发布/articles/{article_id}/sections - 在文章中创建一个部分
  • 删除/articles/{article_id}/sections/{section_id} - 从文章中删除该部分
  • put /articles/{article_id}/sections/{section_id} - 更新基本部分属性,不影响拥有的文章属性,也不影响聚合的部分和项目
  • 等等……

所以我的问题是:

当我收到修改请求时,我会获得元素的所有基本属性以及拥有实体标识符。我怎样才能有效地将它们与数据库中现有的关系结合起来,以便我保留所有它们并修改基本属性,而无需逐一复制所有属性。这是文章-部分关系的示例。

public void modifySection(int articleId, int sectionId, Section section) {
    assert(article.owns(sectionId));
    Section dbSection = sectionDao.findOne(sectionId);
    copyOverProperties(section, dbSection); // this is the thing I do not know how to do
    sectionDao.save(dbSection);
}

【问题讨论】:

标签: java spring hibernate rest


【解决方案1】:

你需要休眠 session.merge(object_name);

链接:From Hibernate docs

我们的 webapp 的编辑功能示例:

   @Repository
    public class GroupCanvasDAOImpl implements GroupCanvasDAO {

        private final SessionFactory sessionFactory;

        @Autowired
        public GroupCanvasDAOImpl(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }
    @Override
        public void editGroupCanvas(GroupCanvas groupCanvas) {
            Session session = this.sessionFactory.getCurrentSession();
            GroupCanvas groupCanvas1 = (GroupCanvas) session.get(GroupCanvas.class, groupCanvas.getMcanvasid());

//  Below 2 steps are not necessary if object was retrieved from DB and //then persisted back-again. If it was newly created to replace an //old-one, then the below 2 lines are needed.
    groupCanvas.setGroupAccount(groupCanvas1.getGroupAccount());
                groupCanvas.setCanvasowner(groupCanvas1.getCanvasowner());
                session.merge(groupCanvas);
                session.flush();
            }
        }
    }

如果这不是你要找的,请告诉我,我会删除我的答案。

【讨论】:

  • 所以在这个会话中,我必须重置所有关系字段,而不是所有基本属性。尽管如此,这对我来说并不是最好的情况,因为我想创建一个可以解决我拥有的各种关系的通用方法。不过,请保留答案 - 我相信它很有用。
  • 你不需要重置所有的关系字段...假设这种情况,你调用一个与其他对象相关联的对象,调用它的getById(int id);。然后您编辑了对象,更改了除 primary_key 之外的其他内容。然后你可以直接调用 session.merge(object_name) 并保持你的关系。
  • 我正在重置关系,因为我们的前端代码有时会创建要编辑的对象(不要问,长篇大论)......这就是我必须重置它们的原因。明白了吗?
  • 好的,但是当我在另一个 bean 实例(来自 Spring MVC)中收到新值时,我必须在这个实例和那个实例之间做一些类似commons.apache.org/proper/commons-beanutils/apidocs/org/apache/…, java.lang.Object)的事情我来自getById(int id)。我需要从这个复制中省略关系,我的问题实际所在的位置。
  • 所以,让我直截了当地说,在一个 bean 实例中(第一个),您调用 getById(int id);然后将对象传递给另一个 bean 实例(第二个),然后对其进行编辑并再次返回到“第一个”实例进行更新。如果是这种情况,您仍然可以使用 session.merge 并在复制属性或克隆 bean 时省略关系(我更喜欢克隆这种情况)。我是否正确理解了您的问题?
猜你喜欢
  • 1970-01-01
  • 2013-04-16
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多