簡體   English   中英

用@Transient 注釋的字段被保存在@DataJpaTest 中

[英]Field annotated with @Transient being persisted in @DataJpaTest

我正在練習 TDD,所以現在我正在嘗試進行暫時失敗的測試。 即將測試目前尚未映射字段關系的@Entity 所以我預計我的測試會失敗。

這是 TableA 實體,您可能會注意到 TableB 關系用@Transient注釋,因此該字段不會保留並且在運行其他集成測試(使用@RunWith(SpringRunner.class)的測試)時不會出錯。

@Builder
@Table(name = "table_a")
@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class TableAData {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Setter
    private String name;

    @Transient
    @Builder.Default
    private List<TableBData> tableBs = List.of();
}

這是 TableB 實體的代碼,沒有什么特別有趣的。

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "table_b")
public class TableBData {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Setter
    private String name;

}

我還有一個 TableAJpaRepository,它擴展了JpaRepository<TableAData, Long>

public interface TableAJpaRepository extends JpaRepository<TableAData, Long> {

    public Optional<TableAData> findByName(String name);

}

我的問題是:為什么 follow test 不下降?

@DataJpaTest
@RunWith(SpringRunner.class)
public class TableAJpaRepositoryIntegrationTest {

    @Autowired
    private TableAJpaRepository repository;

    @Test
    public void dataFechedByIdWhenGetTableBsShouldBringTableB() {
        TableBData tableBItem = TableBData.builder()
            .name("123 Test")
            .build();

        TableAData tableAItem = TableAData.builder()
            .name("TableAEntryName")
            .tableBs(List.of(tableBItem))
            .build();

        Long id = repository.save(archetype).getId();
        repository.flush();


        TableAData fetched = repository.getOne(id);
        assertThat(fetched.getTableBs()).isNotEmpty(); // This should be falling
        assertThat(fetched.getTableBs().get(0).getName()).isEqualTo("123 Test");
    }

}

看起來 getTableBs 方法正在從關系中返回另一個表實體,但我沒有映射它。 我錯過了什么嗎?

所以我和我的朋友花了一些時間試圖弄清楚發生了什么。 我們發現這個 github 問題描述了完全相同的問題。 打開問題的人還創建了一個帶有最小可重現示例的回購協議 另一件很有幫助的事情是這個 SO 答案:你陷入了 JPA 一級緩存的陷阱

看起來是因為緩存。

總而言之,解決方案是:

  • 注入TestEntityManager以持久化並設置測試場景。
  • 始終使用TestEntityManager.persistAndFlush()方法。
  • 在開始測試之前調用TestEntityManager.clear()
  • 存儲庫通常用於測試用例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM