2012-10-18 30 views
6

Tôi đã sử dụng trình xử lý sự kiện Hibernate như PostDeleteEventListener, PostInsertEventListener, PostUpdateEventListener để thực hiện một số thao tác trong khi chèn, xóa và cập nhật. Bây giờ tôi muốn sử dụng trình nghe JPA để làm điều này bởi vì nếu tôi muốn chuyển từ Hibernate sang bất kỳ nhà cung cấp JPA nào khác, trình nghe của tôi sẽ hoạt động. Trình nghe Hibernate cung cấp cho tôi event mà từ đó tôi có thể nhận giao dịch và kiểm tra xem cam kết hoặc khôi phục của nó. Trình lắng nghe JPA chỉ cung cấp cho tôi đối tượng thực thể. Bây giờ làm thế nào tôi có thể nhận được giao dịch hoặc phiên hoặc thực thể manger trong người nghe JPA ?? Cảm ơn trước!! Tôi đang sử dụng Jboss như CMT của tôi.Cách nhận trình quản lý thực thể hoặc giao dịch trong trình nghe jpa

Trả lời

6

này không được hỗ trợ như của JPA 2.0.

Trong JPA 2.1 (dự kiến ​​sẽ có trong Java EE 7), nhà cung cấp kiên trì sẽ xử lý đối tượng lắng nghe như là đĩa CDI khi ở trong môi trường được quản lý (chẳng hạn như máy chủ ứng dụng JBoss). Từ Proposed Final Draft of the JPA 2.1 spec, trang 96:

Entity lớp người nghe trong các môi trường Java EE tiêm hỗ trợ phụ thuộc thông qua API bối cảnh và Dependency Injection (CDI) [10] khi các kho lưu trữ có chứa là một kho lưu trữ đậu. Trình nghe đối tượng lớp sử dụng tính năng tiêm CDI cũng có thể xác định vòng đời các phương thức gọi lại được chú thích bằng chú thích PostConstruct và PreDestroy . Những phương pháp này sẽ được gọi sau khi tiêm đã địa điểm và trước khi dụ thực thể nghe được phá hủy tương ứng

Vì vậy, trong JPA 2.1, nếu bạn tạo một nhà sản xuất CDI cung cấp EntityManager (đơn giản bằng cách chú thích một lĩnh vực @PersistenceContext với @Produces), bạn chỉ có thể @Inject EntityManager vào người nghe.

Đồng thời, tôi không biết về bất kỳ cách giải quyết nào trong sạch hoặc dễ chịu. Điều "tồi tệ nhất" mà tôi có thể nghĩ đến là cấu hình EntityManager bị ràng buộc trong JNDI, sau đó lấy nó thông qua một tra cứu JNDI từ bên trong trình lắng nghe.

-1

Bạn có thể sử dụng tất cả trước/sau tải, chèn, cập nhật hoặc xóa listener trong JPA bằng cách sử dụng hai cách:

  1. Bằng việc sử dụng chú thích. Một ví dụ đơn giản của việc sử dụng một Listener có thể là nơi một thực thể có một biến thoáng qua mà cần phải được dân cư sau khi tổ chức đã tồn, cập nhật hoặc nạp, như:

    public class AvailableCreditListener { 
        @PostLoad 
        @PostPersist 
        @PostUpdate 
        public void calculateAvailableCredit(Account account) { 
         account.setAvailableCredit(
          account.getBalance().add(
          account.getOverdraftLimit())); 
        } 
    } 
    

    Các lớp thực thể sẽ được chú thích với @ EntityListeners:

    @EntityListeners({AvailableCreditListener.class}) 
    public class Account extends BaseEntity { 
        private BigDecimal balance; 
        private BigDecimal overdraftLimit; 
        @Transient 
        private BigDecimal availableCredit; 
        // getters and setters 
    } 
    
  2. Bằng cách sử dụng tệp cấu hình persistence.xml.

Cuối cùng, thay vì chú thích, tệp ánh xạ XMl có thể được sử dụng và triển khai với ứng dụng để chỉ định trình nghe mặc định. (Tệp ánh xạ này được tham chiếu bởi tệp persistence.xml.) Nhưng một thực thể có thể sử dụng chú thích @ExcludeDefaultListeners nếu nó không muốn sử dụng các trình lắng nghe mặc định.

@ExcludeDefaultListeners 
@Entity 
public class Account extends BaseEntity { 
    .... 
} 

Trong persistence.xml của bạn:

<persistence-unit-metadata> 
    <persistence-unit-defaults> 
     <entity-listeners> 
     <entity-listener class="samples.AvailableCreditListener"/>  
     </entity-listeners> 
    </persistence-unit-defaults> 
    </persistence-unit-metadata> 
+6

Câu hỏi của tôi là làm thế nào để có được entityManager trong lớp AvailableCreditListener – Muzy

1

Trong trường hợp của tôi, tôi đang sử dụng mã này:

ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext(); 
auditLogService = (AuditLogService) ctx.getBean("auditLogService"); 

này hoạt động tốt với tôi.

Mã của ứng dụng này hiện có sẵn để tải về tại https://bitbucket.org/macielbombonato/apolo

Tôi hy vọng rằng điều này có thể giúp bạn.

+0

điều này cần được lưu ý là "câu trả lời", nhưng câu trả lời rõ ràng (đối với trường hợp chung) sẽ là, lấy entityManager qua tra cứu JNDI, nhưng ràng buộc cụ thể sử dụng sẽ là container cụ thể (JBoss, Glassfish, Weblogic, v.v.) – him

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