2013-05-04 34 views
5

Giả sử tôi có tình huống sau:Làm thế nào để ánh xạ một ArrayList của nguyên thủy vào một cột đơn?

Ô đối tượng có một ArrayList giá, tất cả đều là số. Có thể trong Hibernate để lưu tất cả giá trong một cột không? Tôi biết điều này vi phạm biểu mẫu bình thường đầu tiên nhưng có thể có trường hợp bạn không muốn chúng được lưu trong một bảng riêng biệt như được thực hiện theo kiểu cổ điển trong mối quan hệ Một-Nhiều hoặc Nhiều-Nhiều.

Trong JDO, tôi sẽ làm điều này một cách dễ dàng bằng cách lưu ArrayList trong cột BLOB.

Một số câu hỏi SOF có liên quan hữu ích: ArrayList of primitive types in HibernateMap ArrayList with Hibernate.

Bất kỳ ý tưởng nào sẽ được đánh giá cao!

Trả lời

5

AFAIR, Hibernate sẽ sử dụng tuần tự hóa gốc và lưu trữ các byte kết quả trong cột của bạn. Tôi sẽ không làm điều đó mặc dù, và sử dụng một chuyển đổi chuyên dụng mà có thể làm giá có thể đọc được trong cơ sở dữ liệu, và ít nhất có thể sử dụng dữ liệu mà không cần Java serialization mẹ đẻ:

@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

Phải. Đó là một điều khác mà tôi đang nghĩ đến. Viết chúng dưới dạng giá trị được phân tách bằng dấu phẩy hoặc một cái gì đó nhưng nó có vẻ giống như một hack. Liên quan đến serialization bản địa, đây là một cái gì đó tôi đã cố gắng và hibernate phàn nàn vì nó không thể ánh xạ List vào một loại cột. Tôi sẽ tiếp tục cố gắng và xem những gì xuất phát từ nó. Cảm ơn rất nhiều cho câu trả lời của bạn. –

1

Bạn có thể thực hiện yout sở hữu kiểu tùy chỉnh như là một mảng:

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

Ngoài ra, không phải là khó để tìm thấy một số hiện thực, một số trong số họ đi xa để cho phép bạn so sánh những mảng trong một HQL mệnh đề where.

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

Cá nhân tôi chưa bao giờ nghĩ tôi sẽ cố gắng một cái gì đó như thế này ... nhưng bây giờ im rất tò mò.

+0

Rất thú vị. Tôi sẽ thử. Cảm ơn bạn! –

11

Tôi biết đây là một câu hỏi cũ nhưng đối với bất cứ ai cố gắng để làm điều này trong một bối cảnh JPA bạn có thể làm điều này

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()); 
     } 
    } 
} 

Sau đó, để sử dụng nó một cái gì đó như thế này trong tổ chức của bạn

@Entity 
public class SomeEntity 
{ 

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

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

    ... 
} 

Thưởng thức !!!

+0

Giải pháp tốt, nhưng lưu ý rằng điều này chỉ có sẵn từ JPA 2.1. – sp00m

Các vấn đề liên quan