有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何更新与hibernate的关系?

我使用的是MSSQL,我有Project模型类,它有字段

@SuppressWarnings("serial")
@Entity(name = "projects")
public class Projects implements Serializable {
    protected static final String PK = "id";
    @OneToOne(mappedBy = "projects", cascade = CascadeType.ALL)
    private Feasibility feasibility;
...
// getters and setters
}

我还有Feasibility对象,它看起来像

@SuppressWarnings("serial")
@Entity(name = "feasibility")
public class Feasibility implements Serializable {

    @Id
    @Column(name = "id")
    private int id;
    @Column(length = 100)
    private String product;
    @Column(name = "launch_date")
    private Timestamp launchDate;
    @Column(length = 40)
    private String status;
    @OneToOne
    @JoinColumn(name = "manager_id", nullable = false)
    private Managers managers;
    @OneToOne
    @JoinColumn(name = "project_id")
    private Projects projects;

// getters and setters
...
}

我还有标准的servicedao对象 服务

public class ProjectsService {
    private ProjectDao projectsDao;

    public ProjectsService() {
        projectsDao = new ProjectDao();
    }

    public void persist(Projects entity) {
        projectsDao.getSessionWithTransaction();
        projectsDao.save(entity);
        projectsDao.closeSessionWithTransaction();
    }

    public void update(Projects entity) {
        projectsDao.getSessionWithTransaction();
        projectsDao.update(entity);
        projectsDao.closeSessionWithTransaction();
    }

    public Projects findById(int id) {
        projectsDao.getCurrentSession();
        return projectsDao.findById(id);
    }

    public void delete(int id) {
        projectsDao.getSessionWithTransaction();
        Projects cbd = projectsDao.findById(id);
        projectsDao.delete(cbd);
        projectsDao.closeSessionWithTransaction();
    }

    public List<Projects> findAll() {
        projectsDao.getSessionWithTransaction();
        List<Projects> costingBriefs = projectsDao.findAll();
        projectsDao.closeSessionWithTransaction();
        return costingBriefs;
    }

    public void deleteAll() {
        projectsDao.closeSessionWithTransaction();
        projectsDao.deleteAll();
        projectsDao.closeSessionWithTransaction();
    }
}

public class ProjectDao implements ActiveRecord<Projects>{
    private Session currentSession;
    private Transaction currentTransaction;

    @Override
    public void save(Projects entity) {
        getCurrentSession().save(entity);
    }

    @Override
    public void update(Projects entity) {
        getCurrentSession().update(entity);
    }

    @Override
    public Projects findById(int id) {
        return getCurrentSession().get(Projects.class, id);
    }

    @Override
    public void delete(Projects entity) {
        getCurrentSession().delete(entity);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Projects> findAll() {
        return (List<Projects>) getCurrentSession().createQuery("from projects").list();
    }

    @Override
    public void deleteAll() {
        List<Projects> entities = findAll();
        for(Projects p : entities)
            getCurrentSession().delete(p);
    }

    public Session getCurrentSession() {
        currentSession = getSessionFactory().openSession();
        return currentSession;
    }

    public Session getSessionWithTransaction() {
        currentSession = getSessionFactory().openSession();
        currentTransaction = currentSession.beginTransaction();
        return currentSession;
    }

    public void closeSessionWithTransaction() {
        currentTransaction.commit();
        currentSession.close();
    }

    private static SessionFactory getSessionFactory() {
        Configuration configuration = new Configuration().configure();
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        return sessionFactory;
    }
}

我可以使用服务将对象添加到表中,但我在更新时遇到问题?我没有得到任何例外,所以很难发现任何问题。我在谷歌上搜索了很多答案,但大多数都建议添加“cascade=CascadeType”。基本上,他们的建议毫无帮助。所以我决定问,我做错了什么

当我从模型Feasibility中列出数据时,当我将其传递给服务更新时,我可以看到更改,但它并没有在数据库中更新

System.out.println("|> " + project.getFeasibility().getProduct()); // I can see here new Product as expected
NewProdForm.getData().getProjectService().update(project);

所以我不确定我做错了什么。我不太了解hibernate,但在阅读文档时,一切看起来都很简单,但并没有给我预期的结果

编辑 另外,我想告诉大家我添加到了hibernate.cfg.xml

<property name="show_sql">true</property>

我只能看到SELECT语句,没有看到任何更新发生,为什么

EDIT2 所以我发现问题的第一个问题是,我只是copy & paste我的代码来自互联网,没有思考到底发生了什么。 解决我问题的第二个问题是方法getCurrentSession我正在打开一个新的Session,这使我的hibernate感到困惑,我应该将它改为:

public Session getCurrentSession() {
    currentSession = getSessionFactory().openSession();
    return currentSession;
}

致:

public Session getCurrentSession() {
    currentSession = getSessionWithTransaction(); // CHANGE IN HERE
    return currentSession;
}

这个改变解决了我的问题

我应该删除帖子吗?我想以后会对其他人有帮助,所以不确定


共 (1) 个答案

  1. # 1 楼答案

    您需要首先按id获取项目实体,以便在会话中加载它,然后在保存之前进行必要的更新,如下所示

    public void update(Projects entity) {
            Project existingProject = projectsDao.findById(entity.getId());
            existingPoject.setAttribute(entity.getAttribute());
            projectsDao.update(existingProject);
        }
    

    上面的代码会让你知道它不是实际的代码