2016-11-16 11 views
6

मुझे एक समस्या है जहां मैं किसी ऑब्जेक्ट को जारी या मर्ज नहीं कर सकता जिसमें केवल एक आईडी और अन्य ऑब्जेक्ट्स का संग्रह होता है। यदि मैं एक और क्षेत्र जोड़ता हूं तो यह लेनदेन को सामान्य के रूप में प्रतिबद्ध करेगा। इसके अलावा, अगर मैं आईडी उत्पादन नीति को ऑटो में बदलता हूं तो यह भी काम करेगा।एक ऐसी संस्था को कैसे बनाए रखें जिसमें केवल एक संग्रह और आईडी हो?

मेरी बाकी टीम "ऑटो" के बजाय "पहचान" का उपयोग करती है, इसलिए मैं उनके साथ संगत होना चाहता हूं। उनकी संस्थाएं सिर्फ एक आईडी + संग्रह से अधिक हैं, इसलिए यह उनके लिए ठीक काम करती है। निम्नलिखित मैं क्या बनाना चाहते है काम:

@Entity 
public class Filter implements Serializable { 

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

    @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL }) 
    private ArrayList<Rule> rules = new ArrayList<>(); 

    public Filter() { 

    } 

} 

त्रुटिसंदेश:

org.apache.openjpa.persistence.PersistenceException: ERROR: syntax error at or near ")" 
    Position: 25 {prepstmnt 693640431 INSERT INTO Filter() VALUES()} [code=0, state=42601] 
FailedObject: [email protected] 

अनिवार्य रूप से, के बाद से यह सिर्फ एक आईडी है और एक टेबल में शामिल हों, यह मर जाता है जब जारी रहती है या फ़िल्टर मर्ज करने का प्रयास बिना किसी खेतों के।

समाधान

  • GenerationType.IDENTITY GenerationType.AUTO को बदलें।

    -इस केवल चोर तो यह मेज पर से 1.

  • GenerationType बदलें बढ़ाने शुरू होता है

    -यह क्या ऑटो प्रतीत हो रहा है, कि प्रारंभिक शुरू कर प्राथमिक कुंजी 50 से आस-पास जाएं प्रतीत हो रहा है उठाया।

  • इकाई के लिए एक मनमाना क्षेत्र जोड़ें (यानी, स्ट्रिंग परीक्षण = "परीक्षण")।

    - बस इकाई बनाने के लिए एक और क्षेत्र बना रहता है। हालांकि, मुझे इस क्षेत्र की आवश्यकता नहीं है; मुझे बस एक संग्रह चाहिए

  • संबंधों को द्विपक्षीय बनाएं।

    - संबंधों को द्विपक्षीय बनाने के द्वारा, तालिकाओं में एक आईडी वापस जा रही है (केवल आईडी होने के बजाय)। यह केवल काम करता है क्योंकि फ़िल्टर का एक और रिकॉर्ड स्वामित्व है।

+0

यदि आपका जेपीए प्रदाता कोई कॉलम के साथ INSERT स्टेटमेंट रखने का समर्थन नहीं करता है तो उस पर एक बीयूजी उठाएं। मैं प्रदाता के साथ ऐसा करता हूं (डेटा न्यूक्लियस) और यह सही एसक्यूएल उत्पन्न करता है। –

+0

ऑटो का उपयोग करना वास्तव में एक उत्तर नहीं है क्योंकि ऑटो का मतलब प्रदाता को छोड़ने की रणनीति है, और वे केवल उसी समस्या के साथ समाप्त होने वाले कवर के तहत पहचान का उपयोग कर सकते हैं। –

+0

लेखक से हटाया गया – garfield

उत्तर

0

एक अच्छा समाधान कोड द्विदिश होगा, जैसा कि आप पहले ही बताया है, और "नियम" वस्तुओं के लिए आईडी सेट करने के लिए "@PrePersist" एनोटेशन का इस्तेमाल करते हैं,। कुछ की तरह:

Rule.java

@Entity 
public class Rule implements Serializable { 

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

    private String description; 

    @ManyToOne 
    private Filter filter; 

    // getters, setters, equals, hashcode, toString... 
} 

Filter.java

@Entity 
public class Filter implements Serializable { 

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

    @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL }, mappedBy="filter") 
    private List<Rule> rules = new ArrayList<>(); 

    @PrePersist 
    public void prePersist() { 
     if (rules != null) { 
      rules.forEach(item -> item.setFilter(this)); 
     } 
    } 

    // getters, setters, equals, hashcode, toString... 
} 

FilterRepository.java

@Repository 
public interface FilterRepository extends JpaRepository<Filter, Integer> { } 

AnUnitTest.java

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class AnUnitTest { 
    @Autowired 
    private FilterRepository filterRepository; 

    @After 
    public void clearDatabase() { 
     bodyPartRespository.deleteAll(); 

     filterRepository.deleteAll(); 
    } 

    @Test 
    public void testFilterRules() { 
     Rule aRule = Rule.builder() 
       .description("A") 
       .build(); 
     Rule anotherRule = Rule.builder() 
       .description("B") 
       .build(); 

     Filter filter = Filter.builder() 
       .rules(Arrays.asList(aRule, anotherRule)) 
       .build(); 

     filterRepository.saveAndFlush(filter); 

     List<Filter> all = filterRepository.findAll(); 

     all.forEach(System.out::println); 
    } 
} 

उपरोक्त कोड मेरे लिए ठीक है।

मुझे आशा है कि यह आपकी समस्या का समाधान करे।

चीयर्स, निकोलस।

0

मैं 4 अलग उदाहरण के साथ अपने समस्याग्रस्त कार्यान्वित:

  1. बस आईडी

    @Entity सार्वजनिक वर्ग Case1 लागू करता Serializable {

    निजी स्थिर अंतिम लंबे serialVersionUID = 1L;

    @ आईडी @ जेनरेटेड वैल्यू (रणनीति = जेनरेशन टाइप .IDENTITY) निजी लांग आईडी;

    // ... }

  2. आईडी + 1 स्ट्रिंग स्तंभ

    @Entity सार्वजनिक वर्ग Case2 लागू करता Serializable {

    निजी स्थिर अंतिम लंबे serialVersionUID = 1L ;

    @ आईडी @ जेनरेटेड वैल्यू (रणनीति = जेनरेशन टाइप .IDENTITY) निजी लांग आईडी; निजी स्ट्रिंग नाम;

    // ... }

  3. आईडी + 1 OneToMany संघ

एक। झरना = {} CascadeType.ALL

> @Entity 
> public class Case3 implements Serializable { 
>   
> private static final long serialVersionUID = 1L; 
>    
> @Id 
> @GeneratedValue(strategy = GenerationType.IDENTITY) 
> private Long id; 
> @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, cascade = { CascadeType.ALL }) 
> private ArrayList<AdminUtilisateur> users = new ArrayList<>();   
> // ... 
>} 

ख के साथ। झरना = {} CascadeType.ALL बिना

> @Entity 
> public class Case4 implements Serializable { 
>   
> private static final long serialVersionUID = 1L; 
>    
> @Id 
> @GeneratedValue(strategy = GenerationType.IDENTITY) 
> private Long id; 
> 
> @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true) 
> private ArrayList<AdminUtilisateur> users = new ArrayList<>();  
> // ... 
>} 

परिणाम एसक्यूएल प्रश्नों (PostgreSQL 9.3 के तहत परीक्षण किया) के साथ ठीक था। लेकिन javax.persistence साथ, मैं मिल गया है एक अलग परिणाम:

  1. केस 1: अपवाद विवरण: फ़ील्ड की सूची तालिका में डालने के लिए [DatabaseTable (case1)] खाली है। आपको इस तालिका के लिए कम से कम एक मानचित्रण को परिभाषित करना होगा।
  2. केस 2: ठीक काम करता है।
  3. केस 3: स्थानीय एक्सेप्शन स्टैक: अपवाद [EclipseLink-4002] (ग्रहण हठ सेवाएं - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DatabaseException आंतरिक अपवाद: org.postgresql.util।PSQLException: ERREUR: la valeur d'une clé dupliquée rompt la contrainte अद्वितीय «rule_code_key»
  4. केस 4: अपवाद विवरण: तालिका में डालने के लिए फ़ील्ड की सूची [डेटाबेसटेबल (case4)] खाली है। आपको इस तालिका के लिए कम से कम एक मानचित्रण को परिभाषित करना होगा।

मामलों 1 पर त्रुटियों की व्याख्या, 3 & 4 सरल है।

  1. केस 3, के लिए आप झरना है जब = {} CascadeType.ALL ORM कोशिश नियमफ़िल्टर बने पहले लागू करने के लिए और सब कुछ, जरूरत पर निर्भर करता है मेरे मामले नियम इसके लिए पहले से ही मौजूद है।

  2. केस 1 & 4 के लिए, आप तालिका N ° 1 और राज करो की आईडी + एक पर फ़िल्टर की आईडी टेबल शामिल हों पर बस की फ़िल्टर आईडी लागू करने के लिए कोशिश कर रहे हैं। जिसका अर्थ है कि फ़िल्टर में केवल आईडी डिज़ाइन समस्या का पर्याय है = आपको इस तालिका के लिए कम से कम एक मैपिंग परिभाषित करना होगा।

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