JPA仓库:在repository.save()后获取CreationTimestamp返回null

huangapple go评论70阅读模式
英文:

JPA repository: Fetching CreationTimestamp after repository.save() returns null

问题

以下是翻译好的部分:

我有以下的结构:

  • BaseEntity类
  • Order实体,它扩展了BaseEntity
  • 地址(嵌入到Order中)

当我将订单保存到数据库时,它会自动填充createdDate和lastModifiedDate。保存后,当我从数据库中获取相同的订单时,createdDatelastModifiedDate会返回为NULL。为什么?

BaseEntity.java

@MappedSuperclass
@Getter
@Setter
public abstract class BaseEntity {
  @Id
  @GeneratedValue(generator = "UUID")
  @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
  @Column(length = 36, nullable = false)
  private UUID id;

  @CreationTimestamp
  @Column(name = "created_date", updatable = false)
  private Timestamp createdDate;

  @UpdateTimestamp
  @Column(name = "last_modified_date")
  private Timestamp lastModifiedDate;
}

OrderEntity.java

@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@Table(name = "order")
public class Order extends BaseEntity {

  private String customer;

  @Embedded
  private Address shippingAddress;
}

以下是失败的测试代码:

@SpringBootTest
class OrderRepositoryTest {

  @Autowired
  private OrderRepository orderRepository;

  @Test
  @Transactional
  @Rollback(value = false)
  public void test_saveOrderHeader() {
    final Order order = Order.builder()
            .customer("first buyer")
            .build();

    final OrderHeader savedOrder = orderRepository.save(order);

    final Optional<Order> fetchedOrder = orderRepository.findById(savedOrder.getId());

    assertNotNull(fetchedOrder);
    assertNotNull(fetchedOrder.get().getId());
    assertNotNull(fetchedOrder.get().getCreatedDate());   //test fails here, getting NULL
    assertNotNull(fetchedOrder.get().getLastModifiedDate());  //getting NULL
  }
}

以下是在调试过程中找到的信息:

savedOrder(测试调试):请注意,fetchedOrder看起来完全相同。在保存的订单中,时间戳可以为空,因为订单尚未完全保存到数据库中。但在fetchedOrder(保存后)中,它不应该为NULL。

但是订单在数据库中以时间戳保存(如下所示)

英文:

I've the following structure:

  • BaseEntity class
  • Order entity which extends BaseEntity
  • Address (embedded into Order)

When I'm saving an order to database, it gets saved with createdDate and lastModifiedDate automatically populated. After save, when I fetch the same order from database, createdDate and lastModifiedDate are returned as NULL. Why ?

BaseEntity.java

@MappedSuperclass
@Getter
@Setter
public abstract class BaseEntity {
  @Id
  @GeneratedValue(generator = &quot;UUID&quot;)
  @GenericGenerator(name = &quot;UUID&quot;, strategy = &quot;org.hibernate.id.UUIDGenerator&quot;)
  @Column(length = 36, nullable = false)
  private UUID id;

  @CreationTimestamp
  @Column(name = &quot;created_date&quot;, updatable = false)
  private Timestamp createdDate;

  @UpdateTimestamp
  @Column(name = &quot;last_modified_date&quot;)
  private Timestamp lastModifiedDate;

OrderEntity.java

@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@Table(name = &quot;order&quot;)
public class Order extends BaseEntity {

  private String customer;

  @Embedded
  private Address shippingAddress;

Below is the test that fails:

@SpringBootTest
class OrderRepositoryTest {

  @Autowired
  private OrderRepository orderRepository;

  @Test
  @Transactional
  @Rollback(value = false)
  public void test_saveOrderHeader() {
    final Order order = Order.builder()
            .customer(&quot;first buyer&quot;)
            .build();

    final OrderHeader savedOrder = orderRepository.save(order);

    final Optional&lt;Order&gt; fetchedOrder = orderRepository.findById(savedOrder.getId());

    assertNotNull(fetchedOrder);
    assertNotNull(fetchedOrder.get().getId());
    assertNotNull(fetchedOrder.get().getCreatedDate());   //test fails here, getting NULL
    assertNotNull(fetchedOrder.get().getLastModifiedDate());  //getting NULL
  }
}

Here is what I found during debugging:

savedOrder (debugging test): Note that fetchedOrder looks exactly same. In saved order, timestamp can be null because order hasn't been saved completely to DB yet. But in fetchedOrder (after savedOrder), it shouldn't be NULL.

JPA仓库:在repository.save()后获取CreationTimestamp返回null

But the order gets saved with timestamp in database (see below):

JPA仓库:在repository.save()后获取CreationTimestamp返回null

So what is going wrong here?

答案1

得分: 0

Hours later, I found the resolution. Here's what worked for me:
since the code that fails is repository test code, I have to use EntityManager as well. Doing entityManager.flush() after saving the Order to database resolved the issue.

Working code:

@SpringBootTest
class OrderRepositoryTest {

  @Autowired
  private OrderRepository orderRepository;

  @Autowired
  private EntityManager em; //added

  @Test
  @Transactional
  @Rollback(value = false)
  public void test_saveOrderHeader() {
    final Order order = Order.builder()
            .customer("first buyer")
            .build();

    final OrderHeader savedOrder = orderRepository.save(order);
    em.flush(); //added 
    final Optional<Order> fetchedOrder = orderRepository.findById(savedOrder.getId());

    assertNotNull(fetchedOrder);
    assertNotNull(fetchedOrder.get().getId());
    assertNotNull(fetchedOrder.get().getCreatedDate());   
    assertNotNull(fetchedOrder.get().getLastModifiedDate());
  }
}
英文:

Hours later, I found the resolution. Here's what worked for me:
since the code that fails is repository test code, I have to use EntityManager as well. Doing entityManager.flush() after saving the Order to database resolved the issue.

Working code:

@SpringBootTest
class OrderRepositoryTest {

  @Autowired
  private OrderRepository orderRepository;

  @Autowired
  private EntityManager em; //added

  @Test
  @Transactional
  @Rollback(value = false)
  public void test_saveOrderHeader() {
    final Order order = Order.builder()
            .customer(&quot;first buyer&quot;)
            .build();

    final OrderHeader savedOrder = orderRepository.save(order);
    em.flush(); //added 
    final Optional&lt;Order&gt; fetchedOrder = orderRepository.findById(savedOrder.getId());

    assertNotNull(fetchedOrder);
    assertNotNull(fetchedOrder.get().getId());
    assertNotNull(fetchedOrder.get().getCreatedDate());   
    assertNotNull(fetchedOrder.get().getLastModifiedDate());
  }
}

</details>



# 答案2
**得分**: 0

以下内容也有效(我猜添加 "Transactional" 是问题所在):

```java
@SpringBootTest
class OrderRepositoryTest {

  @Autowired
  private OrderRepository orderRepository;

  @Test
  public void test_saveOrderHeader() {
    final Order order = Order.builder()
            .customer("第一个买家")
            .build();

    final OrderHeader savedOrder = orderRepository.save(order);
    final Optional<Order> fetchedOrder = orderRepository.findById(savedOrder.getId());

    assertNotNull(fetchedOrder);
    assertNotNull(fetchedOrder.get().getId());
    assertNotNull(fetchedOrder.get().getCreatedDate());   
    assertNotNull(fetchedOrder.get().getLastModifiedDate());
  }
}
英文:

the following also works (I guess adding Transactional was the issue):

@SpringBootTest
class OrderRepositoryTest {

  @Autowired
  private OrderRepository orderRepository;

  @Test
  public void test_saveOrderHeader() {
    final Order order = Order.builder()
            .customer(&quot;first buyer&quot;)
            .build();

    final OrderHeader savedOrder = orderRepository.save(order);
    final Optional&lt;Order&gt; fetchedOrder = orderRepository.findById(savedOrder.getId());

    assertNotNull(fetchedOrder);
    assertNotNull(fetchedOrder.get().getId());
    assertNotNull(fetchedOrder.get().getCreatedDate());   
    assertNotNull(fetchedOrder.get().getLastModifiedDate());
  }
}

huangapple
  • 本文由 发表于 2023年5月26日 16:11:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76338887.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定