6

Spring Data Elasticsearch ile Spring Boot 1.3.1 üzerinde çalışmaya başladım ve veritabanımda kullanılan aynı varlığı kullanmak istiyorum ve bileşik anahtarı var.mümkün bahar-data-elasticsearch @Document bileşik anahtar ile mümkün mü?

Varlık sınıfı:

@IdClass(PassengerPk.class) 
@Table(name = "passenger") 
@Document(indexName="passenger") 
public class Passenger implements Serializable { 

    @Id 
    @ManyToOne 
    @JoinColumn(columnDefinition="long", name="user_id", referencedColumnName="id") 
    private User user; 

    @Id 
    @ManyToOne 
    @JoinColumn(columnDefinition="long", name="scheduler_id", referencedColumnName="id") 
    private Scheduler scheduler; 

    @Column(name = "is_active") 
    private Boolean isActive; 

    ... 
} 

Anahtar sınıfı:

public class PassengerPk implements Serializable { 

    private Long user; 
    private Long scheduler; 

    public PassengerPk() { 
    } 

    public PassengerPk(Long user, Long scheduler) { 
     this.user = user; 
     this.scheduler = scheduler; 
    } 
    ... 
} 

JPA Elasticsearch deposu:

public interface PassengerSearchRepository extends ElasticsearchRepository<Passenger, PassengerPk> { 

} 

Veritabanı: database relationships

Bu kodu derlemeye çalışırsam, bu hatayı alıyorum.

Caused by: java.lang.IllegalArgumentException: Unsuppored ID type class com.dualion.test.domain.PassengerPk 
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactory.getRepositoryBaseClass(ElasticsearchRepositoryFactory.java:79) ~[spring-data-elasticsearch-1.3.1.RELEASE.jar:na] 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepositoryInformation(RepositoryFactorySupport.java:238) ~[spring-data-commons-1.11.1.RELEASE.jar:na] 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:181) ~[spring-data-commons-1.11.1.RELEASE.jar:na] 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251) ~[spring-data-commons-1.11.1.RELEASE.jar:na] 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237) ~[spring-data-commons-1.11.1.RELEASE.jar:na] 
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean.afterPropertiesSet(ElasticsearchRepositoryFactoryBean.java:55) ~[spring-data-elasticsearch-1.3.1.RELEASE.jar:na] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE] 
    ... 71 common frames omitted 

Kodumu nasıl değiştirebilirim?

Teşekkür

+0

Herkes bana bir çözüm önerebilir mi? – kn4ls

+0

@ IdClass'ın bağımlılığını nasıl devralıyorsunuz?JPA ile JPA arasındaki bazı bağımlılıkların getirdiği bir sınıf olduğunu düşünüyorum. Nasıl yapılacağını bilmiyorum. Tabii ki ES için kullanamazsın. Bu arada, hedefinize nasıl ulaşacağınızı bilmek benim için çok yararlı olacaktır. – andPat

+0

Son olarak, HibernateSearch kullanın ve ES değil, beacause uygulaması daha kolaydır. – kn4ls

cevap

0

Ben başka hiçbir yerde yanıt ilişkili okumuştu ve bu mümkün değildi sonucuna vardı; Ancak, inatçılığım en iyiliydi ve ben bir çözüm buldum.

TLDR; Kompozit kimliğinizin hashCode'unu alan ve String değerini kendi kimliği olarak kullanan yeni bir depo kullanmak için yayı zorlayın.

Adımlar ...

kompozit kimlikleri kapasitesine sahip yeni bir Repository oluşturun: Bu işe doğru kompozit id sınıfına .hashCode uygulayan varsayar olduğunu

public class HashKeyedRepository<T, ID extends Serializable> extends AbstractElasticsearchRepository<T, ID> { 

    public HashKeyedRepository() { 
     super(); 
    } 

    public HashKeyedRepository(ElasticsearchEntityInformation<T, ID> metadata, 
           ElasticsearchOperations elasticsearchOperations) { 
     super(metadata, elasticsearchOperations); 
    } 

    public HashKeyedRepository(ElasticsearchOperations elasticsearchOperations) { 
     super(elasticsearchOperations); 
    } 

    @Override 
    protected String stringIdRepresentation(ID id) { 
     return String.valueOf(id.hashCode()); 
    } 
} 

Not.

@EnableElasticsearchRepositories(basePackages = "xxx.xxx.repository.search", repositoryFactoryBeanClass = CustomElasticsearchRepositoryFactoryBean.class) 

Bu uygulama geri düşüyor: En depoları etkinleştirirken

public class CustomElasticsearchRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends ElasticsearchRepositoryFactoryBean<T, S, ID> { 

    private ElasticsearchOperations operations; 

    public CustomElasticsearchRepositoryFactoryBean(Class<? extends T> repositoryInterface) { 
     super(repositoryInterface); 
    } 

    public void setElasticsearchOperations(ElasticsearchOperations operations) { 
     super.setElasticsearchOperations(operations); 
     Assert.notNull(operations);  
     this.operations = operations; 
    } 

    @Override 
    protected RepositoryFactorySupport createRepositoryFactory() { 
     return new ElasticsearchRepositoryFactory(operations) { 
      @Override 
      protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) { 
       if (!Integer.class.isAssignableFrom(metadata.getIdType()) && !Long.class.isAssignableFrom(metadata.getIdType()) && !Double.class.isAssignableFrom(metadata.getIdType()) && metadata.getIdType() != String.class && metadata.getIdType() != UUID.class) { 
        return HashKeyedRepository.class; 
       } 
       return super.getRepositoryBaseClass(metadata); 
      } 
     }; 
    } 
} 

Son olarak, belirtmek yeni RepositoryFactoryBean sınıf:

Sonraki Bu Repository yeni dönecektir yeni RepositoryFactoryBean oluşturmak zorunda Bu yazının desteklediği kimliklerden herhangi biri yerine kullanılırsa (yani, Dize, UUID, Sayı) varsayılana. .hashCode ile çakışma olasılıkları olduğunu ancak bunun benim için şu anda çalışmakta olduğunu gösteren BÜYÜK bir çözüm olup olmadığını bilmiyorum.

PS Ben auto lombok s @Data benim için .hashCode oluşturmak kullanıyorum.

PPS Başkalarının (java olmayan) sözünü gördüğüm başka bir çözüm, tablonun (örneğin JSON) serileştirilmiş bir sürümünü kodlamak üzere base64 olmasıdır. Bence bu, herhangi bir çatışmayı garanti etmese de, fazla karakterleri (yani, beyaz boşlukları) ve emin olmak için özelliklerin garanti sırasını kesinleştirdiğinizden emin olmalısınız.