【问题标题】:JPA Transient annotationJPA 瞬态注释
【发布时间】:2017-10-15 01:59:58
【问题描述】:

我在学习SpringHibernate

我已阅读以下和其他教程资源。 我的理解是@Transient 会阻止对象字段序列化并阻止它持久化到数据库中。

Transient variable in java

Transient annotation

JPA Transient annotation and JSON

我的问题是,如果您有一个对象的字段,但您不想保留到数据库,但又希望在从服务器获取数据时检索该字段,该怎么办?

例如,在您的 MySql createDate 设置为 CURRENT_TIMESTAMP 时,当插入数据时,我的 MySql 会创建 TIMESTAMP

MySql 是这样设置的

ALTER TABLE `books` 
ADD COLUMN `dateCreated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP AFTER `dateCreated`;

我的控制器是

@RequestMapping(path="/booklist", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Map<String, Object> getListBooks(@RequestParam(name="search", required=false) String search, 
                @RequestParam(name="ordering", required=false) String ordering){


    Map<String, Object> data = new HashMap<String, Object>();

    // Get list of books from server
    List<Book> books = bookDao.getBookList(search, ordering);

    System.out.println(books.get(0));

    // do other things and return map
}

我的返回数据是

Book [id=1, name=Murach Jquery, 2rd Edition, ispn=978-1890774912, price=4.24, dateCreated=null, datePublished=null]

我的书对象如下

@Entity
@Table(name="books")
@Component
public class Book implements Serializable{

    private static final long serialVersionUID = -2042607611480064259L;

    @Id
    @GeneratedValue
    private int id;

    @NotBlank
    private String name;

    @NotBlank
    @Size(min=2, max=16)
    private String ispn;

    @DecimalMin(value = "0.1")
    private double price;

    @Transient
    private Timestamp dateCreated;

    private Date datePublished;

    // getter and setters

}

谢谢。

【问题讨论】:

  • @Transient 属性不会持久化到数据库中,而只会添加到 JSON 响应中。您可能需要在dateCreated 属性上添加@Temporal 注释。
  • 你关心的只是createDate吗?
  • 如果你没有持久化它,你会从哪里检索它。一旦会话关闭,任何不持久的东西都会消失。
  • @AbdullahKhan 是的,所有其他字段都非常正常,发送到 db 并从 db 获取是正常的,只是 dateCreated 有点令人困惑,因为日期是由 MySql 设置的,而不是在应用程序端。还是您认为我设置的方式不合逻辑,应该在应用程序上创建日期。
  • @Mohit 我已经用 MySql 中的表格代码更新了我的问题。 MySql 将在插入数据时创建一个 TIMESTAMP。所以我的控制器将调用bookDao.getBookList() 来检索书籍对象。

标签: java spring hibernate jpa jackson


【解决方案1】:

对字段使用@Formula 注释并传递列。见the example

@Formula("createDate")
private Timestamp dateCreated;

【讨论】:

  • 但我不想计算任何东西。
  • 无需计算。只需像往常一样使用该列。实体字段不存储,而是从数据库中检索。
【解决方案2】:

@Transient 不会为您提供帮助。

在实体类中的方法上使用@PrePersist

@PrePersist
public void beforePersist() {
    this.dateCreated = new Date();
}

beforePersist() 方法用 @PrePersist 注释将帮助您在要持久化新实体之前自动初始化实体字段。对于您的情况,您可以在此方法中初始化您的 date 属性。您不必在每次持久化 实体时手动设置它。

现在,当您从数据库中获取实体时,您将获得日期属性。

还可以查看@PreUpdate,它可以帮助您在更新实体时更新实体字段。

【讨论】:

  • 我的时间戳是MySql在插入数据时设置的。所以我不想在应用程序端设置日期。您认为在应用程序端设置日期更好吗?
  • 我在过去的 4-5 个项目中一直在设置Date,但从未遇到麻烦。此外,它还会从您的基础数据库中删除日期依赖性。
  • 我明白了...我可以问您其他问题吗?这超出了问题范围,但是如果您的应用程序是国际的new Date() 不设置本地机器时间怎么办?而不是 UTC 时间?
  • 查看thisthis 问题。
  • 非常感谢您提供的这些链接,它对我帮助很大。
猜你喜欢
  • 2014-11-01
  • 2016-11-30
  • 2012-01-06
  • 1970-01-01
  • 2011-04-27
  • 2018-06-22
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
相关资源
最近更新 更多