यह मेरी इकाई है:

@Builder
@Data
@Entity
@Table(name = "audit_log")
public class AuditEventEntity {
    @Id
    @GeneratedValue
    private UUID id;

    private long createdEpoch;

    @NotNull
    @Size(min = 1, max = 128)
    private String label;

    @NotNull
    @Size(min = 1)
    private String description;
}

और यह मेरा भंडार है:

@Repository
public interface AuditEventRepository extends PagingAndSortingRepository<AuditEventEntity, UUID> {
}

जब मैं भंडार के लिए निम्नलिखित इकाई परीक्षण लिखता हूं, तो "लेबल" फ़ील्ड शून्य होने पर भी सहेजना सफल होता है!

@DataJpaTest
@RunWith(SpringRunner.class)
public class AuditRepositoryTest {
    @Test
    public void shouldHaveLabel() {
        AuditEventEntity entity = AuditEventEntity.builder()
                .createdEpoch(Instant.now().toEpochMilli())
                .description(RandomStringUtils.random(1000))
                .build();
        assertThat(entity.getLabel()).isNullOrEmpty();
        AuditEventEntity saved = repository.save(entity);
        // Entity saved and didn't get validated!
        assertThat(saved.getLabel()).isNotNull();
        // The label field is still null, and the entity did persist.
    }

    @Autowired
    private AuditEventRepository repository;
}

चाहे मैं @NotNull या @Column(nullable = false) का उपयोग करूं, डेटाबेस कॉलम पर not null ध्वज के साथ बनाया गया है:

Hibernate: create table audit_log (id binary not null, created_epoch bigint not null, description varchar(255) not null, label varchar(128) not null, primary key (id))

मैंने सोचा था कि सत्यापनकर्ता स्वचालित रूप से काम करेंगे। मुझसे यहां क्या गलत हो रहा है?

5
Paul 27 जून 2018, 17:30

1 उत्तर

सबसे बढ़िया उत्तर

मैंने सोचा था कि सत्यापनकर्ता स्वचालित रूप से काम करेंगे। मुझसे यहां क्या गलत हो रहा है?

आप निकाय को सहेजते हैं लेकिन आप वर्तमान निकाय प्रबंधक की स्थिति को फ़्लश नहीं करते हैं.
इसलिए इकाई का सत्यापन अभी तक नहीं किया गया है।

आप हाइबरनेट सत्यापनकर्ता अक्सर पूछे जाने वाले प्रश्न :

जब मैं लगातार () कहता हूं, तो मेरी जेपीए इकाई को मान्य क्यों नहीं किया जाता है?

जब मैं persist() पर कॉल करता हूं तो मेरी जेपीए इकाई की पुष्टि क्यों नहीं होती है? कम उत्तर है EntityManager#flush() पर कॉल करें यदि आप सत्यापन करना चाहते हैं ट्रिगर किया गया।

हाइबरनेट ओआरएम और कुछ अन्य ओआरएम जितने ऑपरेशन को बैचने का प्रयास करते हैं डेटाबेस तक पहुँचने पर संभव है। संभावना है कि वास्तविक इकाई "निरंतर" ऑपरेशन केवल तभी होता है जब आप flush() को कॉल करते हैं या जब लेन-देन करता है।

साथ ही, यह जानना कि कौन सी इकाई कायम रहने वाली है, आपकी कैस्केडिंग रणनीति और आपके ऑब्जेक्ट ग्राफ़ की स्थिति पर निर्भर करती है। फ्लश तब होता है जब हाइबरनेट ओआरएम उन सभी संस्थाओं की पहचान करता है जिन्हें बदल दिया गया है और डेटाबेस क्रियाओं की आवश्यकता होती है (HHH-8028 भी देखें)।

इसलिए इकाई को सत्यापित करने की अनुमति देने के लिए JpaRepository.save() के बजाय JpaRepository.saveAndFlush() का उपयोग करें।
या वैकल्पिक रूप से टेस्ट क्लास में एक EntityManager या एक TestEntityManager इंजेक्ट करें, JpaRepository.save() को इनवाइट करें और फिर EntityManager/TestEntityManager.flush() को इनवाइट करें।

जानकारी के लिए :

JpaRepository.save() आह्वान em.persist(entity)/em.merge(entity)
JpaRepository.saveAndFlush() JpaRepository.save() और फिर em.flush() को कॉल करता है


saveAndFlush() का आह्वान करने में सक्षम होने के लिए, आपको अपने रिपोजिटरी इंटरफ़ेस को JpaRepository विस्तारित करना होगा जैसे:

public interface AuditEventRepository extends  JpaRepository<AuditEventEntity, UUID> {

जैसे-जैसे JpaRepository PagingAndSortingRepository का विस्तार करता है, यह परिवर्तन आपकी मौजूदा घोषणा के अनुरूप रहता है।


मैं जोड़ूंगा कि इस दावे की आवश्यकता नहीं है:

assertThat(saved.getLabel()).isNotNull();

आप जो कहना चाहते हैं वह यह है कि ValidationException फेंक दिया गया है और हो सकता है कि इसमें वास्तविक त्रुटि संदेश हो।

4
davidxxx 27 जून 2018, 18:10