2009-10-18 27 views
5

mới để mùa xuân và đây @stackoverflowXuân @Transactional sáp nhập và tồn tại câu hỏi

Tôi đang xây dựng một kho độc lập & Sales theo dõi ứng dụng (Apache Pivot/Spring/JPA/Hibernate/MySQL) cho một doanh nghiệp phân phối .

Cho đến nay tôi nghĩ mọi thứ đều là CRUD, vì vậy tôi dự định có một lớp cơ sở với mọi thứ @Transactional.

Sau đó, tôi gặp sự cố với phương pháp lưu chung của tôi. Phương pháp liên tục và hợp nhất của EntityManager từ Spring có sự khác biệt không?

Tôi đã thử chạy và được gọi là lưu cho cả chèn và cập nhật và nó hoạt động tốt (tôi nghĩ mùa xuân sẽ tự động làm mới thực thể mỗi khi tôi gọi phương thức lưu của mình // thấy các truy vấn ngủ đông được ghi lại, đúng không?).

@Transactional 
public abstract class GenericDAO { 

    protected EntityManager em; 

// em [email protected]/setter 

    public void save(T t) { 
//  if (t.getId() == null) // create new 
//  { 
//   em.persist(t); 
//  } else // update 
//  { 
      em.merge(t); 
//  } 
    } 
} 

Và btw, có thiết lập như thế này, tôi sẽ không ảnh hưởng nhiều đến hiệu suất phải không? Giống như gọi salesDAO.findAll() để tạo báo cáo (không cần phải giao dịch, phải không?).

cảm ơn !!!

Trả lời

5

This SO question là một cuộc thảo luận tốt về kiên trì so với hợp nhất và câu trả lời được chấp nhận giải thích rõ ràng. Câu trả lời khác cũng liên kết đến một bài đăng trên blog tốt về điều này.

Theo câu trả lời đầu tiên trong this other post, có vẻ như có thể gọi hợp nhất để lưu và cập nhật một thực thể, nhưng đó không phải là cách tôi đã thực hiện. Trong các ứng dụng Spring/JPA của tôi, tôi chỉ có DAO của mình mở rộng JpaDaoSupport và sử dụng getJpaTemplate() theo cách sau.

/** 
* Save a new Album. 
*/ 
public Album save(Album album) { 
    getJpaTemplate().persist(album); 
    return album; 
} 

/** 
* Update an existing Album. 
*/ 
public Album update(Album album) { 
    return getJpaTemplate().merge(album); 
} 
+0

Tôi đánh dấu đây là cách đơn giản nhất. Vì vậy, nếu tôi có JpaDaoSupport, và tôi nhận được một thực thể từ nó, bất kỳ thay đổi sẽ được tự động cam kết? Tôi nghĩ rằng tôi sẽ có hai biến thể của phương pháp lưu, một phương pháp vẫn tồn tại và một biến thể tuôn ra. Bất kỳ bình luận về điều này? – thirdy

+0

Bạn có nghĩa là tự động như đã cam kết mà không lưu hoặc cập nhật không? Nếu vậy, tôi sẽ không nghĩ như vậy, tôi luôn luôn chỉ cần gọi lưu trên một thực thể mới hoặc cập nhật trên một hiện có để tồn tại. Tôi đã không bao giờ cần thiết để gọi phương pháp tuôn ra, nhưng truy cập DB của tôi là khá đơn giản cho bất kỳ yêu cầu nhất định. –

+0

Tôi sẽ phải từ bỏ việc thử Mùa xuân ngay bây giờ. Chỉ cần tò mò, làm thế nào Grails cải thiện về điều này? Tôi sẽ không gặp phải những vấn đề như thế này ở Grails phải không? – thirdy

4

Các link đến đầu kia SO câu hỏi Kaleb đăng tải không làm tốt công việc của bao gồm sự khác biệt và gotchas của tồn tại() vs merge(). Tuy nhiên, tôi đã luôn luôn triển khai thực hiện các lớp Dao của tôi với một phương thức save() mà chỉ gọi merge() để xử lý cả chèn và cập nhật, và tôi chưa bao giờ chạy vào bất kỳ gotchas persist() vs merge() nào. Theo các phương thức hoạt động chỉ đọc sẽ không thực sự ảnh hưởng đến hiệu suất, mặc dù tôi thích sử dụng chú thích ở cấp phương thức để tôi có thể dễ dàng biết phương thức nào là bản cập nhật và đang đọc. Bạn có thể làm điều này bằng cách đặt thuộc tính readOnly trên chú thích @Transactional.

Nếu bạn làm theo một quy ước đặt tên trong các phương pháp của bạn (tức là bất kỳ phương pháp đọc luôn bắt đầu với getXXX), bạn cũng có thể sử dụng cú pháp poincut trong tập tin cấu hình mùa xuân của bạn để tự động làm cho sự khác biệt này:

<tx:advice id="txAdvice" transaction-manager="txManager"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true"/> 
     <tx:method name="*"/> 
    </tx:attributes> 
    </tx:advice> 

Xem Spring documentation on Transactions để biết thêm thông tin.

Ngoài ra, tôi thường đặt thuộc tính @Transactional một cấp cao hơn các lớp Dao của tôi, trong một lớp dịch vụ. Các phương thức trên các lớp Dao sau đó là các hoạt động cơ sở dữ liệu riêng biệt cho mỗi cuộc gọi phương thức, trong khi các phương thức dịch vụ có thể thực hiện một cam kết/rollback duy nhất cho một loạt các bản cập nhật.

+0

cảm ơn bạn đã trả lời. Tôi nghĩ rằng tôi sẽ dính vào JPA tinh khiết, (tôi không cần nhiều sự linh hoạt) – thirdy