【问题标题】:Entity properties are not changing after calling dao.findByID(id)调用 dao.findByID(id) 后实体属性没有改变
【发布时间】:2017-09-27 16:49:34
【问题描述】:

这里的问题是为什么在调用实体的某些设置器后没有保存实体属性。通常在更改托管实体的属性时,它应该传播到数据库。

看看这个例子:

@Service
public class SystemServiceImpl implements SystemService {

@Autowired
private SystemDao systemDao;


@Override
@Transactional
public System replace(Long systemID) {

    // External system to replace
    System system = systemDao.findByID(systemID);
    if (null != system) {
        system.setName("Test"); // Calling findByID again shows that this call did not have any effect.
    }
    return system;
}

}

-

@Entity
@Table(name = "db.system")
public class System {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long systemID;

private String name;

@OneToMany(mappedBy = "system", fetch = FetchType.LAZY)
@JsonIgnore
private List<Customer> customers = new ArrayList<Customer>();

public Long getSystemID() {
    return systemID;
}

public void setSystemID(Long systemID) {
    this.systemID = systemID;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public List<Customer> getCustomers() {
    return customers;
}

public void setCustomers(List<Customer> customers) {
    this.customers = customers;
}
}

如果我在 system.setName("Test") 之后调用 systemDao.merge,那么它会保存到数据库中。我觉得我不应该调用合并,因为这应该是一个托管实体。

我尝试使用和不使用 @Transactional 的 replace 方法,两者都产生相同的结果。

有什么想法吗?

谢谢,

【问题讨论】:

  • 能否添加@entity类,特别是定义不触发更新的列
  • 也不是一些更高级别的事务方法的替换方法部分吗?
  • 更新了答案,replace方法也是自定义方法,只存在于我创建的界面中。
  • 你在打电话给.save()吗?我认为如果不调用.save() 或任何其他相关方法,数据库将得到更新。
  • Afaik,如果它是托管的,你不需要调用保存。

标签: java spring hibernate entitymanager


【解决方案1】:

如果 SystemDao.findByID() 返回一个分离的对象,则可以解释该行为。确保 SystemDao 不使用 RequiresNew-Transaction 或在加载对象后显式分离对象。 如果您发布 SystemDao 的代码和任何相关的配置条目(Spring、实体管理器配置......),这将非常有帮助。

【讨论】:

  • 为什么实体会在 findByID 之后分离?如果这是可能的,那么请提供可能发生的方式。也许我可以在我的源代码中搜索一个示例配置。
  • 如果你明确地分离它 em.detach(object) 或调用 em.clear(),实体可以分离。如果代码在单独的事务中运行,它也可以分离,如上所述。
  • 我可以告诉你,我的 dao 扩展了 HibernateDaoSupport。我也在运行 Spring 3.2。
  • 如果不发布您的 SystemDao 代码和配置,我们将无法帮助您。根据您上面所说,一切都表明对象在不同的​​事务中加载,而不是在修改时不是当前会话的一部分。顺便提一句。不推荐使用 HibernateDaoSupport。
  • 公共接口 SystemDao extends HibernateDaoSupport { System findByName(String name); }
【解决方案2】:

在我运行集成测试时发生了错误。事实证明 Transactional 没有做任何事情,因为没有会话。解决这个问题的方法是在我的测试中添加一个事务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    相关资源
    最近更新 更多