2012-02-21 15 views
5

Tôi không sử dụng Spring nên tôi đang tạo một cá thể của EntityManager trong một lớp.Hibernate EntityManager, nó được cho là được sử dụng như một singleton?

Tôi đã sử dụng kỹ thuật đảo ngược Hibernate-Eclipse để tự động tạo các lớp. Tất cả các lớp này đều có một thể hiện của EntityManager.

Tôi không chắc chắn cách Hibernate làm việc với EntityManager vì vậy tôi tự hỏi liệu có nhiều trường hợp của lớp này (EntityManager) được tạo, ví dụ, sẽ có vấn đề với giao dịch?

Tôi có nên tạo một lớp riêng biệt phân phối một thể hiện tĩnh của một EntityManager cho tất cả các lớp khác của tôi không? hay nó không quan trọng?

EDIT: Tôi thấy có một cái gì đó được gọi là @PersistenceContext, dường như không tải persistence.xml của tôi là một bean trong biến thể hiện, tính năng này có yêu cầu mùa xuân không? (Tôi nhận được null pointer ngoại lệ, bởi vì nó không bao giờ được tiêm)

snip mã từ nơi tôi cố gắng sử dụng @persistencecontext

@PersistenceContext(unitName = "manager1") 
private EntityManager entityManager; 

persistence.xml tôi

<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
      version="2.0"> 
    <persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 

     <properties> 

     <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 
     <property name="javax.persistence.jdbc.user" value="root"/> 
     <property name="javax.persistence.jdbc.password" value="mypassword"/> 
     <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/ptbrowserdb"/> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> 
     </properties> 
    </persistence-unit> 
</persistence> 
+0

Bạn có thể xóa công cụ sửa đổi truy cập riêng tư (trên 'EntityManager') và kiểm tra không? – Santosh

Trả lời

10

Xem bài viết này: JPA Architecture giải thích rất rõ.

Nói chung, bạn cần một Trình quản lý thực thể duy nhất cho mỗi giao dịch. Và người quản lý thực thể này không được sử dụng trong hai giao dịch cùng một lúc.

Clairification: Ý tôi là, không sử dụng một Trình quản lý thực thể duy nhất cho đơn vị công việc khác. Một giao dịch điển hình trong một đơn vị công việc, nếu bạn có các giao dịch khác nhau của một đơn vị công việc, thì bạn có thể sử dụng cùng một Trình quản lý thực thể

Nếu bạn sử dụng Spring thì Spring thực hiện việc xử lý này cho bạn nếu bạn sử dụng chú thích @PersistenceContext để tiêm EntityManager. Theo mặc định, Spring "liên kết" EntityManager được tiêm (thông qua proxy) với giao dịch hiện tại. (Và giao dịch được "ràng buộc" với chủ đề.)

@See Spring Reference 13.5.2 Implementing DAOs based on plain JPA - nó chứa một đoạn văn thú vị sau các ví dụ mã.

+0

lol bạn không cần một người quản lý thực thể duy nhất cho mỗi giao dịch. Một người quản lý thực thể đại diện cho một phiên mở (kết nối) đến cơ sở dữ liệu, rất tốn kém của nó chỉ để sử dụng nó cho một giao dịch. 1 phiên cho mỗi hoạt động được coi là một mẫu giả mạo! https://developer.jboss.org/wiki/Sessionsandtransactions – Maurice

+0

@Maurice: Đây là một bài viết thú vị, nhưng nó là về mô hình Session/SessionFactory "cũ" của Hibernate, nhưng câu hỏi này là về JPA. Như giá vé như tôi biết điều này trong một trong những chủ đề hiếm hoi mà JPA và Hibernate-Session khác nhau. Hãy xem chương "5.1. Phạm vi quản lý thực thể và phạm vi giao dịch" trong https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/transactions.html - nó tuyên bố: "Một EntityManager là không tốn kém , đối tượng không an toàn nên được sử dụng một lần, cho một quy trình nghiệp vụ duy nhất, một đơn vị công việc và sau đó bị loại bỏ. " – Ralph

+0

và một quy trình nghiệp vụ có thể bao gồm nhiều giao dịch phải không? Hay bạn không đồng ý. Không phải họ nói trong liên kết của tôi mà tôi phải đặt nhiều hơn sau đó một giao dịch trong một phiên nếu không nó sẽ là một antipattern? – Maurice

1

Bạn cần một sự phụ thuộc khuôn khổ tiêm như Spring hoặc Google Guice để tiêm các đối tượng vào lớp của bạn nếu không nó có thể không được tiêm tự động cho bạn. Về cơ bản, đây là một chú thích được JPA cung cấp, nó sẽ hoạt động song song với khung ngủ đông hoặc bất kỳ khung ORM nào khác nói nhưng bạn cần một khung công tác DI để tiêm các đối tượng.

Về trường hợp duy nhất của người quản lý thực thể, tôi không nghĩ rằng bạn cần điều đó nếu bạn đi trước mùa xuân vì nó quản lý các trường hợp và giao dịch cho bạn bằng cách buộc người quản lý thực thể của bạn với giao dịch jpa.

+1

Trong J2EE bạn không cần bất kỳ khuôn khổ tiêm phụ thuộc bên ngoài nào. Các mũi tiêm được xử lý bởi các container. – Santosh

+0

Bạn không cần khuôn khổ Dependency Injection: bạn có thể thực hiện nó theo cách riêng của mình: trong một ứng dụng web ví dụ với một địa phương tread đang nắm giữ trình quản lý thực thể và EntityManagerPerRequestPatternFilter – Ralph

+0

@Ralph - Có, tôi đồng ý chúng ta có thể tự mình tiêm để tránh chi phí, chúng tôi đã chứng minh các khuôn khổ cho DI..spring hoặc guice sẽ liên tục làm điều đó cho chúng tôi ..cung cấp những điều này nên là một phần của ngăn xếp ứng dụng .. – raddykrish

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