2013-05-04 12 views
5

Załóżmy, że mam następującą sytuację:Jak zmapować ArrayList z prymitywów do jednej kolumny?

Obiekt Samochód ma ArrayList cen, które są liczbami. Czy w Hibernate można zapisać wszystkie ceny w jednej kolumnie? Wiem, że to narusza pierwszą normalną formę, ale mogą istnieć przypadki, gdy nie chcesz, aby były zapisywane w osobnej tabeli, tak jak to się robi w klasycznych relacjach One-To-Many lub Many-To-Many.

W JDO zrobiłbym to łatwo, zapisując ArrayList w kolumnie BLOB.

Kilka przydatnych powiązanych pytań SOF: ArrayList of primitive types in Hibernate i Map ArrayList with Hibernate.

Każdy pomysł będzie bardzo ceniony!

Odpowiedz

5

AFAIR, Hibernate użyje rodzimej serializacji i zapisze wynikowe bajty w kolumnie. Nie zrobiłby tego, choć i użyć dedykowanego transformację, która stałaby ceny czytelny w bazie danych, a przynajmniej być w stanie wykorzystać dane bez konieczności Java Native serializacji:

@Basic 
private String prices; 

public void setPrices(List<Integer> prices) { 
    this.prices = Joiner.on(',').join(prices); 
} 

public List<Integer> getPrices() { 
    List<Integer> result = new ArrayList<Integer>(); 
    for (String s : Splitter.on(',').split(this.prices)) { 
     result.add(Integer.valueOf(s)); 
    } 
    return result; 
} 
+0

Dobrze. To była kolejna rzecz, o której myślałem. Napisz je jako wartości rozdzielone przecinkami lub coś w tym stylu, ale wydawało się, że to hack. Powiązany z natywną serializacją, jest to coś, co próbowałem i hibernate narzekałem, ponieważ nie mógł zamapować Listy na typ kolumny. Będę nadal próbował i zobaczę, co z tego wyniknie. Wielkie dzięki za odpowiedź. –

1

można zaimplementować yout właścicielem niestandardowy typ jako tablica:

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/types.html#types-custom

Ponadto, nie jest to, że trudno jest znaleźć niektóre implementacje, niektóre z nich idzie tak daleko, aby porównać te tablice w a HQL gdzie klauzuli.

https://forum.hibernate.org/viewtopic.php?t=946973

Ja osobiście nigdy nie pomyślałem, że chciałbym spróbować coś takiego ... ale teraz jestem bardzo ciekawy.

+0

Bardzo interesujące. Dam temu szansę. Dziękuję Ci! –

11

wiem, jest to stara sprawa, ale dla każdego, kto stara się zrobić to w kontekście JPA można to zrobić

import org.apache.commons.lang3.StringUtils; 
import javax.persistence.AttributeConverter; 
import javax.persistence.Converter; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
import java.util.stream.Collectors; 
import java.util.stream.Stream; 

@Converter 
public class IntArrayToStringConverter implements AttributeConverter<List<Integer>,String>{ 
    @Override 
    public String convertToDatabaseColumn(List<Integer> attribute) { 
     return attribute == null ? null : StringUtils.join(attribute,","); 
    } 

    @Override 
    public List<Integer> convertToEntityAttribute(String dbData) { 
     if (StringUtils.isBlank(dbData)) 
      return new ArrayList<>(); 

     try (Stream<String> stream = Arrays.stream(dbData.split(","))) { 
      return stream.map(Integer::parseInt).collect(Collectors.toList()); 
     } 
    } 
} 

Potem go używać coś takiego w swojej jednostce

@Entity 
public class SomeEntity 
{ 

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

    @Column 
    @Convert(converter = IntArrayToStringConverter.class) 
    private List<Integer> integers; 

    ... 
} 

Cieszyć się !!!

+0

Przyjemne rozwiązanie, ale pamiętaj, że jest to dostępne tylko od wersji 2.1 JPA. – sp00m

Powiązane problemy