java - 是否应该在进入 Java 之前克隆 Date 对象

标签 java spring hibernate

我听说 Date 不是线程安全的问题,但还没有找到任何实际的解释,这可能会导致糟糕的结果。我知道用 DateFormat 解析时会很糟糕,但是 Date

作为一个例子,使用下面的 Date 会导致多线程环境变得很糟糕吗?

@Transactional(rollbackFor = {Throwable.class})
public void moveToArchive(UserContext userContext, long id) throws PostFailedException {
        PostEntity postEntity;
        try {
            postEntity = postDAO.get(userContext.getUserId(), id);
        } catch (EntityNotFoundException ex) {
            throw new PostFailedException(PostFailedException.ITEM_NOT_FOUND, ex);
        }
        //...
        // copying java.util.Date between entities
        archivedPostEntity.setCreationDate(post.getCreationDate());
        //...
}

那么如果 getCreationDate 仅返回内部属性会很糟糕吗?或者 Spring/Hibernate 会正确处理这个问题吗?

getCreationDate 应该是什么样子?

这样的事情可以吗?

@Entity
public class PostEntity implements Post {
//...
    @NotNull
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date postDate;
//... 
    @Override
    public Date getPostDate() {
        return postDate;
    }
}

或者也许应该更像这样?

@Entity
public class PostEntity implements Post {
//...
    @NotNull
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date postDate;
//... 
    @Override
    public synchronized Date getPostDate() {
        return new Date(postDate.getTime());
    }
}

最佳答案

Java Date 对象不是线程安全的。您通过 getPostDate() 方法创建新日期的方法将在很大程度上避免此问题。事实上,这被认为是最佳实践。

现在,无论线程安全如何,建议您在从实体返回时重新创建(克隆或其他方式)Date 对象。 FindBugs 实际上会在您的 POJO 中查找此问题。原因是 Date 是可变的,与 String 类不同。

因此,从实体 bean 返回实时引用允许更改实体中的 Date 对象,而无需在实体中使用相应的 set 方法。该实体将不知道其内部状态是否已更改以及是否需要将其保留到数据存储中。这种缺陷发生的频率比您愿意承认的要高。

希望这能回答您的问题。

关于java - 是否应该在进入 Java 之前克隆 Date 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47796565/

相关文章:

Java Hibernate在插入用户名和密码时获取实体ID并将其删除

java - 如何查找mongodb中嵌入嵌套数组的长度?

sql - 无法删除或更新父行 - 使用 Hibernate 的 JPA

java - 如何测试(java)流畅的 API?

java - spring-hibernate transaction-变化没有反射(reflect)?

java - 将 RequestBody json 转换为对象 - Spring Boot

java - Spring LocaleResolver 链接

java - 单元测试模拟注入(inject)

Spring + Hibernate Search动态配置

java - 以编程方式将项目 JAR 部署到 Artifact