【问题标题】:Default value in newly created row isn't loaded未加载新创建行中的默认值
【发布时间】:2017-10-31 13:59:19
【问题描述】:

我有一个 MySQL 表:

mysql> show create table items\G
*************************** 1. row ***************************
       Table: items
Create Table: CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.02 sec)

我通过 Entity 类从 Java 程序创建新行:

@Entity
@Table(name = "items", schema = "office_db")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Items.findAll", query = "SELECT i FROM Items i"),
    @NamedQuery(name = "Items.findById", query = "SELECT i FROM Items i WHERE i.id = :id"),
    @NamedQuery(name = "Items.findByName", query = "SELECT i FROM Items i WHERE i.name = :name"),
    @NamedQuery(name = "Items.findByCreated", query = "SELECT i FROM Items i WHERE i.created = :created")
})
public class Items implements Serializable {

    @Column(name = "name",length = 128)
    private String name;
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "created")
    @Temporal(TemporalType.TIMESTAMP)
    private Date created;
    @OneToMany(mappedBy = "itemId")
    private Collection<Documents> documentsCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "items")
    private Collection<ItemAttributes> itemAttributesCollection;
    (more stuff ...)

我只设置了NAME列,和预期的一样,默认设置了ID和CREATED:

mysql> select * from items;
+----+--------+---------------------+
| id | name   | created             |
+----+--------+---------------------+
|  2 | Case 2 | 2017-10-31 13:47:52 |
|  3 | Case 3 | 2017-10-31 13:48:02 |
+----+--------+---------------------+
2 rows in set (0.00 sec)

但是,当我稍后在同一会话中将表重新加载到 Java 中时:

public List<Items>findItems(){
    TypedQuery<Items> query=
            em.createNamedQuery("Items.findAll",Items.class);

    return query.getResultList();
}

ID 列已正确加载,但 CREATED 列显示为空白。如果我重新启动应用程序(它在 glassfish 服务器上运行),CREATED 会正确显示。我的猜测是,造成这种差异的原因是 ID 上的 @GeneratedValue 注释,但我不能将它应用于 CREATED 字段,看起来,或者至少不是天真。使生成的时间戳加载的正确方法是什么?

【问题讨论】:

  • 当你持久化一个对象时,调用了什么 SQL INSERT 语句?那么当您执行查询时,它从哪里获取对象?从数据存储?还是来自 L1/L2 缓存?看日志
  • 我没有在日志中看到它(该域的 server.log) - 我看到的只是代码中的 INFO 日志输出,用于跟踪正在发生的事情。我将不得不研究 Glasshfish 设置,看看我是否可以看到 SQL 等。任何指向该方向的指针将不胜感激。
  • 它是您选择的任何 JPA 提供程序,因此请查看他们的文档以了解其日志所在的位置
  • 嗯,我现在似乎完全破坏了 Glassfish 中的日志记录。我刚刚将其中一个记录器设置更改为 FINE,现在它不起作用。无论如何,我认为从症状中得出结论是安全的,INSERT 仅设置 NAME col,并且重新加载似乎只是使用缓存。有没有办法强制它从表中加载选择?
  • 重新登录 - 为了其他遇到相同问题的人的利益:在域目录中找到 logging.properties;就我而言,属性“com.sun.enterprise.server.logging.GFFileHandler.level”应设置为“ALL”(或至少不是“OFF”)

标签: java mysql jpa


【解决方案1】:

看来,我的难题的答案是调用em.refresh(),根据此:Invalidating JPA EntityManager session - 这是针对 Hibernate,但对于 EclipseLink 似乎是一样的。就我而言,我遇到了一个例外,但我会在另一个问题中发布。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 2012-03-07
    • 1970-01-01
    • 2021-04-30
    相关资源
    最近更新 更多