2014-10-07 3 views
5

इसलिए मेरा डेटाबेस मॉडल इस प्रकार है: मेरे पास Store एस है और प्रत्येक Store का स्थानीय नाम है।स्प्रिंग डेटा जेपीए के साथ मानचित्र मूल्यों के लिए कैसे पूछें?

@Embeddable 
public class LocalizedValue { 

    @Column(name = "value") 
    private String value; 
} 

और यह सब:

public class Store { 
    private Map<Locale,LocalizedValue> name; 
} 

के रूप में आप यह <Locale, LocalizedValue> का एक मानचित्र जहां LocalizedValue इस तरह एक वर्ग है देख सकते हैं: तो मैं एक Map इस तरह के रूप में स्थानीय नाम का प्रतिनिधित्व करने के लिए चुना है बहुत अच्छा काम करता है। हालांकि मुझे एक समस्या है जहां मैं अपने स्प्रिंग डेटा जेपीए रिपोजिटरी से पूछताछ करना चाहता हूं और दिए गए अंग्रेजी नाम के साथ सभी स्टोर ढूंढना चाहता हूं। तो मेरी भंडार विधि इस प्रकार है:

Store findByName(Map.Entry<Locale, LocalizedValue> name); 

लेकिन यह इस अपवाद फेंकता है: तो फिर

2014-10-07 23:49:55,862 [qtp354231028-165] ERROR: Parameter value [en=Some Value] did not match expected type [com.test.LocalizedValue(n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [en=Some Value] did not match expected type [com.test.LocalizedValue (n/a)] 
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [en=Some Value] did not match expected type [com.test.LocalizedValue (n/a)]; 
nested exception is java.lang.IllegalArgumentException: Parameter value [en=Some Value] did not match expected type [com.test.LocalizedValue (n/a)] 
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384) 
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:216) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417) 
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) 
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) 

मैं बदल मेरी भंडार विधि इस तरह होने के लिए:

Store findByName(LocalizedValue name); 

लेकिन फिर मैं यह अपवाद मिला:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'name1_.pk' in 'where clause' 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526) 

मैंने क्वेरी विधि में कंटेनिंग का उपयोग करने का भी प्रयास किया - अभी भी कोई भाग्य नहीं है।

तो मेरा सवाल है: क्या स्टोर नाम के लिए अंग्रेजी नाम 'कुछ मूल्य' के साथ पूछताछ करने का कोई तरीका है?

उत्तर

7

यह इस तरह एक मैन्युअल रूप से परिभाषित क्वेरी कुछ की आवश्यकता है।

+2

आपके उत्तर के लिए धन्यवाद। क्या यह स्प्रिंग जेपीए में प्रलेखित है? वसंत जेपीए द्वारा नक्शा मूल्यों का विस्तार कैसे किया जाता है, इस बारे में मुझे और जानकारी कहां मिल सकती है। – Sharadr

+0

संग्रह पैरामीटर के साथ भी किया जा सकता है? – mihn

1

आपने अपनी मैपिंग पोस्ट नहीं की हैं लेकिन मुझे लगता है कि एंबेडेबल्स की कुंजी के साथ मुझे एक मौलिक मुद्दा माना जाता है।

यह केवल स्पष्ट तरह से मैं संघ मैप करने के लिए देख सकते हैं:

@Entity 
@Table(name = "stores") 
public class Store { 

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

    @ElementCollection 
    @CollectionTable(name = "store_names", joinColumns = @JoinColumn(name = "store_id")) 
    @MapKeyColumn(name = "locale") 
    private Map<Locale, LocalizedName> names; 

    public Map<Locale, LocalizedName> getNames() { 
     return names; 
    } 

    public String getName(Locale locale) { 
     return names.get(locale).getName(); 
    } 
} 


@Embeddable 
public class LocalizedName { 

    @Column(name = "name") 
    private String name; 

    @SuppressWarnings("unused") 
    private LocalizedName() { 

    } 

    public LocalizedName(String name) { 
     this.name = name; 
    } 

    public String getName(){ 
     return name; 
    } 
} 

निम्नलिखित परीक्षण में सफ़ल:

@Test 
public void testLoadStore() { 
    Store store = repository.findOne(1l); 
    Assert.assertNotNull(store); 
    Assert.assertEquals("EN Name", store.getName(Locale.ENGLISH)); 
    Assert.assertEquals("DE Name", store.getName(Locale.GERMAN)); 
} 

इस के साथ इस मुद्दे हालांकि यह है कि 'पता लगाएं' कभी नहीं हो सकता स्थानीयकृत नाम की एक संपत्ति अन्यथा डुप्लिकेट कॉलम मैपिंग की शिकायतें हाइबरनेट करें।

https://hibernate.atlassian.net/browse/HHH-5393

इसलिए जब यह संभव है एक प्रश्न विधि लिखने के लिए:

सार्वजनिक इंटरफ़ेस StoreRepository फैली JpaRepository {

@Query(value = "from Store s join s.names n where n.name = ?1") 
Store findByName(String name); 

}

जिसके लिए

बग रिपोर्ट देखें निम्नलिखित परीक्षा पास

@Test 
public void testLoadByName() { 
    Store store = repository.findByName("EN Name"); 
    Assert.assertNotNull(store); 
    Assert.assertEquals("EN Name", store.getName(Locale.ENGLISH)); 
    Assert.assertEquals("DE Name", store.getName(Locale.GERMAN)); 
} 

जहां तक ​​मैं इसे देख सकता हूं, कभी भी लोकेल को खाते में नहीं ले सकता क्योंकि यह स्थानीयकृत नाम की संपत्ति नहीं है।

interface StoreRepository extends Repository<Store, Long> { 

    @Query("select s from Store s join s.map m where ?1 in (VALUE(m))" 
    Optional<Store> findByName(String name); 
} 

यह मूल रूप से नक्शा मूल्यों का विस्तार और जाँच करें कि क्या दिए गए पैरामीटर का विस्तार किया मानों की सूची में है करने के लिए हठ प्रदाता बताता है:

+0

नहीं, बेशक यह काम नहीं करेगा - आप लोकेल को कभी निर्दिष्ट नहीं करते हैं। मैंने कोशिश की और मुझे मिलता है: "पैरामीटर मान [कुछ मूल्य] अपेक्षित प्रकार से मेल नहीं खाता [com.test.LocalizedValue (n/a)];" –

+0

अद्यतन उत्तर देखें। –

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