2011-01-30 22 views
11

Tôi đã sau "gốc" thực thể (phần ngủ đông cụ thể chú thích):tách các đơn vị JPA từ Hibernate cụ thể tinh chỉnh

@Entity 
//@GenericGenerator(name="system-uuid",strategy="org.hibernate.id.UUIDGenerator") 
public class Node extends PersistentEntity { 
    private UUID id; 
    private String name; 
    private String displayName; 

    @Id 
    @GeneratedValue 
    //@GeneratedValue(generator="system-uuid") //instead of above line 
    //@Type(type = "pg-uuid") 
    public UUID getId() { return id; } 

    public String getName() { return name; } 

    public String getDisplayName() { return displayName; } 

    //stuff omitted 
} 

này là một phần của một bối cảnh kiên trì triển khai trên JBoss AS 6 (hibernate 3.6) sử dụng PostgreSQL 9 cho cơ sở dữ liệu (sử dụng trình điều khiển JDBC4 mới nhất). PostgreSQL có kiểu cột uuid riêng của nó, yêu cầu một số ánh xạ cụ thể ngủ đông để sử dụng đúng (nhận xét trong mã trên) - nếu không hibernate sẽ cố ánh xạ trường UUID tới BINARY, thì phương ngữ PostgreSQL không hỗ trợ BINARY (rõ ràng là vì postgre có 2 cách để lưu trữ devs và hibernate devs không thích nó) và toàn bộ điều phát nổ.

bỏ ghi chú các dòng ở trên tạo mã hoạt động, nhưng nó buộc tôi phải có thời gian biên dịch phụ thuộc vào chế độ ngủ đông - mà tôi muốn tránh.

cố gắng để thêm một tập tin hbm.xml vào trộn và tham khảo nó từ persistence.xml không kết hợp dữ liệu từ các tập tin và các chú thích, nhưng chỉ đơn giản là bỏ qua các chú thích:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="package"> 
    <class name="Node"> 
     <id name="id" type="pg-uuid"> 
      <generator class="org.hibernate.id.UUIDGenerator"/> 
     </id> 
    </class> 
</hibernate-mapping> 

tôi có thể "làm bù xù "này nộp lên bằng cách thêm thêm 2 thuộc tính, nhưng ngay cả khi tôi làm điều đó (lúc này các công trình lớp Node), thêm bất kỳ thực thể thêm, như:

@Entity 
public class Host extends Node { 
    //fields, getters, fluff 
}

tôi nhận được ngoại lệ sau đây:

org.hibernate.DuplicateMappingException: Duplicate class/entity mapping Node

vì hibernate "tìm thấy" Nút hai lần. có cách nào tao nhã quanh đây không? lý tưởng, Node là lớp duy nhất mà tôi sẽ cần các thuộc tính đặc trưng ngủ đông, và nó sẽ là gốc của một hệ thống phân cấp lớn của các lớp. tôi muốn tránh phụ thuộc thời gian biên dịch trên hibernate hoặc lập bản đồ tất cả mọi thứ hoàn toàn trong hbm.xml. cho đầy đủ vì lợi ích, đây là tập tin persistence.xml im sử dụng:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> 
    <persistence-unit name="myPU" transaction-type="JTA"> 
     <jta-data-source>java:/my-postgresql-DS</jta-data-source> 
     <mapping-file>META-INF/hbm.xml</mapping-file> 
     <!-- shouldnt need to list classes here since this is deployed --> 
     <!-- in the same jar as the classes and scanning should work --> 
     <validation-mode>AUTO</validation-mode> 
     <properties> 
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/> 
     </properties> 
    </persistence-unit> 
</persistence> 
+0

Tôi đã kiểm tra "Java Persistence với JPA" (một JPA 2,0 -book), nhưng nó không nói bất cứ điều gì về UUIDs, vì vậy tôi cho rằng chúng chưa được hỗ trợ bởi JPA. – esaj

+0

chúng được hỗ trợ ít nhất theo nghĩa là bất kỳ thứ gì có thể tuần tự hóa được hỗ trợ (sẽ chuyển thành dữ liệu nhị phân). nhưng với PostgreSQL + Hibernate bạn sẽ không nhận được ngay cả điều đó ... – radai

Trả lời

0

Câu trả lời là nó không thể được thực hiện (ít nhất là trong JPA 2.0)

0

Bạn có thể thử bỏ @ Entity-chú thích ra khỏi Node-class, và bản đồ nó hoàn toàn trong hbm.xml, hoặc liệt kê tất cả các các lớp ngoại trừ Node trong persistence.xml và sử dụng < exclude-unlisted-classes />, sau đó ánh xạ nó trong hbm.xml. Không có ý tưởng nếu một trong những phương pháp tiếp cận này thực sự hoạt động, phương pháp thứ hai có thể thực sự ngăn cản hbm.xml ánh xạ lớp.

+0

thả @Entity từ Node kết quả trong "Không có định danh được chỉ định cho [bất cứ điều gì mở rộng Node]". giữ @Entity trên Node trong khi cố gắng "thu hẹp" ánh xạ (với phần loại trừ) vẫn dẫn đến một vụ va chạm (vì nó trèo lên cây thừa kế và vẫn tìm thấy nó, tôi đoán) – radai

1

Tôi có một vài đề xuất có thể đơn giản hóa hoặc định tuyến xung quanh vấn đề, mặc dù tôi không trả lời câu hỏi cụ thể của bạn về hbm.xml.

1) Bạn có thể tạo ID theo cách thủ công. Để lại @GeneratedValue và tôi tin rằng bạn chỉ có thể sử dụng Java UUID.randomUUID() để tạo UUID tuân thủ RFC 4122 như máy phát điện 'uuid2' của Hibernate. Tôi đã không sử dụng máy phát cụ thể đó trong Hibernate, nhưng nếu tất cả những gì bạn muốn là UUID hợp lệ, có vẻ như việc tạo thủ công nó có thể giúp bạn tránh được một số điệu nhảy cấu hình.

2) Cá nhân tôi chỉ lưu trữ UUID (mặc dù không có cột id) trong PostgreSQL trong cột VARCHAR. Tôi tìm thấy khi nó đến thời gian cho cơ sở dữ liệu sleuthing, tôi cắt và dán UUIDs từ các tập tin đăng nhập, và nó làm cho nó dễ dàng hơn để truy vấn. Khi UUID được lưu trữ như BINARY, nó là không thể, đó là lý do tại sao chúng tôi thay đổi chúng thành varchar. Chúng tôi coi các cột UUID nhưng varchar làm cho rất nhiều điều đơn giản hơn và cải thiện khả năng tương tác. Nó không quan trọng để đóng gói chuyển đổi String-to-UUID trong lớp Java của bạn.

Tất nhiên bạn có thể phải sử dụng loại cột UUID vì lý do cũ hoặc bạn có thể thích nó vì lý do hiệu suất.Ít nhất một người đã thực hiện một performance comparison of the two approaches.

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