2017-12-18 93 views
6

पैकेज java.time से value based classes हैं। यदि मेरे पास ऐसी वस्तु का उपयोग करने वाली इकाई है जो फ़ील्ड के रूप में है, तो मैं निम्नलिखित "समस्या" में चलाता हूं: मूल्य आधारित कक्षाओं को क्रमबद्ध नहीं किया जाना चाहिए। हालांकि, जेपीए इकाई को इंटरफेस सीरियलज़ेबल को कार्यान्वित करना है। उस विरोधाभास का समाधान क्या है? क्या किसी को जेपीए इकाई के क्षेत्र के रूप में स्थानीयडेटाइम का उपयोग नहीं करना चाहिए? इसके बजाय तिथि का उपयोग करें? यह असंतुष्ट होगा।जावा.टाइम और जेपीए

यह समस्या एक सोनार नियम squid:S3437 है और इसलिए वहाँ, क्योंकि हम LocalDateTime करने की तारीख से बदल परियोजना में कीड़े का एक बहुत हैं ...

गैर अनुरूप मूल्य आधारित वर्ग उपयोग के कारण समाधान:

@Entity 
public class MyEntity implements Serializable{ 
    @Column 
    private String id; // This is fine 
    @Column 
    private LocalDateTime updated; // This is not ok, as LocalDateTime is a value based class 
    @Column 
    private Date created; // This however is fine.. 
} 
+4

क्यों नरक में आपको लगता है कि मूल्य आधारित कक्षाओं को क्रमबद्ध नहीं किया जाना चाहिए? बेशक वे serialized किया जा सकता है। यही कारण है कि यह Serializable लागू करता है। –

+0

अच्छी तरह से हमारे पास यह कहानी अच्छी तरह से है, क्योंकि समय के लिए हम केवल '@SuppressWarnings ("squid: S3437") हैं, अभी के लिए, dev-list पर एक टिप्पणी है (मैं इसे खोदने की कोशिश करूंगा) यह कहता है कि यह * मूल्य * आधारित * वर्ग * को मूल्य आधारित * प्रकार * – Eugene

+0

@JBNizet में स्थानांतरित करने के लिए इन मान आधारित * कक्षाओं को प्रतिबंधित कर सकता है यह वास्तव में स्थानीयडेटाइम के बारे में अजीब बात है। यह एक मूल्य आधारित वर्ग भी है। यदि आप ऑर्केकल दस्तावेज में देखते हैं तो आपको मूल्य आधारित कक्षाओं के बारे में निम्न कथन मिलेगा: https: // docs।oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html एक प्रोग्राम अप्रत्याशित परिणाम उत्पन्न कर सकता है यदि यह दो संदर्भों को मान-आधारित वर्ग के बराबर मानों में अंतर करने का प्रयास करता है [... ] क्रमबद्धता, या किसी अन्य पहचान-संवेदनशील तंत्र। इस तरह के उपयोग [...] अप्रत्याशित प्रभाव हो सकता है और इससे बचा जाना चाहिए। – itsme

उत्तर

2

मेरा उत्तर काफी प्रत्यक्ष और बेकार लग सकता है, लेकिन यह चीजों को एक साथ लाने और सारांशित करने के लिए और अधिक है।

पहली बात यह है कि इस समस्या का कोई "सुनहरा बुलेट" समाधान नहीं है। कुछ निश्चित रूप से परिवर्तित करने की है और मैं 3 विकल्प या 3 विकल्प देखें:

  1. Serializable इंटरफ़ेस निकालें। यह सभी इकाइयों पर Serializable डालने के लिए "अच्छा अभ्यास" नहीं है। इसकी आवश्यकता केवल तभी होती है जब आप इसे अलग-अलग वस्तुओं के रूप में उपयोग करने जा रहे हैं: When and why JPA entities should implement Serializable interface?

  2. स्थानीयडेटाइम के बजाय टाइमस्टैम्प प्रकार का उपयोग करें। मुझे ऐसा लगता है कि यह बराबर है: डिफ़ॉल्ट रूप से

https://github.com/javaee/jpa-spec/issues/63

त्वरित, LocalDateTime, OffsetDateTime, और ZonedDateTime नक्शे के रूप में टाइमस्टैम्प मान। उस संपत्ति को जारी रखने के लिए आप एक अलग रणनीति निर्दिष्ट करने के लिए @TeMPOraL के साथ इन प्रकारों में से किसी एक की संपत्ति को चिह्नित कर सकते हैं।

  1. दोनों पहले विकल्प आपके लिए काम नहीं करते हैं, तो (मैं कर रहा हूँ यकीन है कि, आप क्या करना है पता है) - यह चेतावनी @SuppressWarnings("squid:S3437") को दबाने।
+1

जैसा नहीं किया जाना चाहिए, मैं आपके उत्तर को समाधान के रूप में चिह्नित करता हूं, क्योंकि इसका उपयोग "समस्या" को हल करने के लिए किया जा सकता है। हालांकि मुझे राहत महसूस नहीं होती है, जब मुझे किसी समस्या का समाधान होता है तो मुझे सामान्य लगता है :) इसका कारण यह है कि: क्यों पृथ्वी पर स्थानीय डेटाटाइम दोनों मूल्य आधारित और सीरियलज़ेबल है। यह बहुत अजीब लगता है ... – itsme

+1

@itsme जेडीके -9 में 'अपरिवर्तनीय' संग्रहों के लिए लागू होता है, उन्हें दस्तावेज में मूल्य-प्रकार घोषित किया जाता है लेकिन वे 'Serializable' – Eugene

+0

@Eugene को जानना अच्छा लगाते हैं। क्या आप इसके पीछे तर्क जानते हैं? – itsme

1

मुझे समझ में नहीं आता कि आप डीबी से जेबी स्वीकार करते हैं। जब मैं Postgres के साथ सौदा है, मैं एक स्वनिर्धारित कनवर्टर का उपयोग:

import javax.persistence.AttributeConverter; 
import javax.persistence.Converter; 
import java.sql.Timestamp; 
import java.time.LocalDateTime; 

@Converter(autoApply = true) 
public class LocalDateTimePersistenceConverter implements AttributeConverter<LocalDateTime, Timestamp> { 

    @Override 
    public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) { 
     return (locDateTime == null ? null : Timestamp.valueOf(locDateTime)); 
    } 

    @Override 
    public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) { 
     return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime()); 
    } 
} 

और मैं इसे इस तरह का उपयोग करें:

@Column(name = "create_date") 
@Convert(converter = LocalDateTimePersistenceConverter.class) 
private LocalDateTime createDate; 

तुम देखो, यहाँ मैं (postgres द्वारा स्वीकार कर लिया) समय-चिह्न को LocalDateTime और वापस परिवर्तित।

+0

मेरा प्रश्न यह नहीं था कि जेपीए के साथ लोकलडेटाइम का उपयोग कैसे करें, लेकिन धारावाहिक है, लेकिन मूल्य आधारित आधार का उपयोग करने के विरोधाभास को कैसे हल किया जाए। कृपया मेरा प्रश्न सावधानी से पढ़ें;) इसका जवाब नहीं है – itsme

+0

जिस तरीके से आपने अपना प्रश्न बनाया है उसे समझना मुश्किल है। Serializable एक मार्कर है और आपको किसी भी विधि को लागू करने की आवश्यकता नहीं है। यह सिर्फ बताता है कि इस वर्ग का एक उदाहरण आरएमआई के माध्यम से स्थानांतरित किया जा सकता है या फ़ाइल सिस्टम में सहेजा जा सकता है। कोई दायित्व नहीं इसमें कोई प्रतिबंध नहीं है कि आपको जेपीए इकाई के क्षेत्र के रूप में स्थानीयडेटाइम का उपयोग नहीं करना चाहिए और मैंने इसका एक उदाहरण उदाहरण पोस्ट किया है। LocalDateTime को परिवर्तित किया जा सकता है और अब आपके पास नमूना कोड है। – dimirsen

+0

आपके उत्तर के लिए धन्यवाद, लेकिन मेरे प्रश्न में कहीं भी मैंने उल्लेख नहीं किया कि स्थानीयडेटाइम का रूपांतरण काम नहीं कर रहा है। यह serializable <-> मूल्य आधारित के बारे में एक सामान्य प्रश्न है और क्यों स्थानीयडेटाइम में यह दोनों है, लेकिन उसी समय यह – itsme

संबंधित मुद्दे