2010-01-23 38 views
8

Có thể lưu trữ một số thứ như sau chỉ sử dụng một bảng không? Ngay bây giờ, những gì hibernate sẽ làm là tạo ra hai bảng, một cho gia đình và một cho mọi người. Tôi muốn đối tượng familymembers được tuần tự hóa vào cột trong cơ sở dữ liệu.Lưu trữ các đối tượng trong các cột bằng cách sử dụng Hibernate JPA

@Entity(name = "family") 
class Family{ 

    private final List<Person> familyMembers; 

} 

class Person{ 

    String firstName, lastName; 
    int age; 

} 
+0

Đây không phải là rõ ràng. Nếu bạn đang thấy familly như một nhóm người, thì bạn cần một bảng mới cho familly, ngoại trừ nếu bạn đại diện cho familly với một kiểu đơn giản như một số nguyên hoặc một chuỗi. – Kartoch

+1

OT: Đó sẽ là một thiết kế tồi. –

+0

Nếu gia đình có 3 thành viên, bạn sẽ thấy giá trị nào trong cột cơ sở dữ liệu? –

Trả lời

0

Bạn có thể tạo pseudoproperty (getter và setter) mà chấp nhận/trả về dưới dạng tuần tự hóa và chú thích các familyMembers với @Transient. Điều này cũng cần phải chú thích các getters, chứ không phải các trường, cho tất cả các thuộc tính khác.

1

Chú thích thuộc tính với @Column và xác định loại là ArrayList, không chỉ List. Và thực hiện Person triển khai Serializable.

Nhưng bạn nên làm điều này chỉ khi động cơ của bạn rất rõ ràng, bởi vì đây là giải pháp đúng trong một số trường hợp rất hiếm. Như Pascal đã lưu ý, nếu bạn phải thay đổi Person bạn sẽ bị đau đầu.

+0

Tôi khá chắc chắn rằng điều này sẽ thất bại với một 'java.lang.ClassCastException: java.util.ArrayList không thể được đưa vào java.sql.Blob' –

+0

có, tôi đã xem xét một lớp của tôi, nơi tôi có tình huống tương tự - nó hoạt động withotu Lob, và với việc xác định loại bê tông (ArrayList).Cập nhật câu trả lời – Bozho

13

Đây là thiết kế khủng khiếp và tôi thực sự không đề xuất nó (bạn chỉ nên tạo một bảng khác) nhưng có thể.

Trước tiên, bạn sẽ cần phải sử dụng thuộc tính byte[] để giữ phiên bản được sắp xếp theo thứ tự của danh sách những người sẽ được lưu trữ trong BLOB trong cơ sở dữ liệu. Vì vậy, chú thích nó getter với @Lob (Tôi sẽ làm cho getter và setter private để không lộ chúng). Sau đó, hiển thị getter "giả" và setter để trả lại hoặc đặt một số List<Person> từ số byte[]. Tôi đang sử dụng SerializationUtils từ Commons Lang trong mẫu dưới đây (cung cấp cho bạn lớp helper riêng nếu bạn không muốn nhập thư viện này) để sắp xếp/deserialize khi đang di chuyển đến/từ số byte[]. Đừng quên để đánh dấu getter "giả" với @Transcient hoặc Hibernate sẽ cố gắng tạo ra một lĩnh vực (và thất bại vì nó sẽ không thể xác định loại cho một List).

@Entity(name = "family") 
class Family implements Serializable { 

    // ... 

    private byte[] familyMembersAsByteArray; 

    public Family() {} 

    @Lob 
    @Column(name = "members", length = Integer.MAX_VALUE - 1) 
    private byte[] getFamilyMembersAsByteArray() { // not exposed 
     return familyMembersAsByteArray; 
    } 

    private void setFamilyMembersAsByteArray((byte[] familyMembersAsByteArray() { // not exposed 
     this.familyMembersAsByteArray = familyMembersAsByteArray; 
    } 

    @Transient 
    public List<Person> getFamilyMembers() { 
     return (List<Person>) SerializationUtils.deserialize(familyMembersAsByteArray); 
    } 

    public void setParticipants(List familyMembers) { 
     this.familyMembersAsByteArray = SerializationUtils.serialize((Serializable) familyMembers); 
    } 
} 

Đừng quên để làm cho Person lớp Serializable và để thêm một thực serialVersionUID (Tôi chỉ thấy một mặc định ở đây):

public class Person implements Serializable { 

    private static final long serialVersionUID = 1L; 

    // ... 

    private String firstName, lastName; 
    private int age; 

} 

Nhưng, hãy để tôi nhấn mạnh, đây là một thiết kế khủng khiếp và nó sẽ rất mong manh (thay đổi Person có thể yêu cầu "di chuyển" nội dung của BLOB để tránh các vấn đề deserialization và điều này sẽ trở nên đau đớn. Bạn nên thực sự xem xét lại ý tưởng này và sử dụng một bảng khác cho Person thay vào đó (hoặc tôi không 't nhận được lý do tại sao bạn sử dụng cơ sở dữ liệu)

+0

tại sao bạn không thể sử dụng cơ sở dữ liệu người, có thể vì sử dụng nó là vô nghĩa? Nếu tất cả những gì tôi cần là lưu trữ một danh sách thứ gì đó, tôi không cần phải đặt nó trong cơ sở dữ liệu riêng biệt. – Enerccio

1
@Type(type = "serializable") 
private List<Person> familyMembers; 

nếu bạn không thể sử dụng chú thích ngủ đông thử điều này:

@Lob 
private Serializable familyMembers; 

public List<Person> getFamilyMembers(){ 
    return (List) familyMembers; 
} 

public void setFamilyMembers(List<Person> family){ 
    familyMembers = family; 
} 
+1

Có, nhưng Đây không phải là chú thích JPA. –

+0

xem cập nhật câu trả lời –

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