2012-06-21 32 views
17

Tôi đang làm một ứng dụng web bằng cách sử dụng Spring 3.1.0.RELEASE, JSF 2.x, JPA 2 với Hibernate Provider, MySql 5.1.x. Ứng dụng chạy trên Tomcat 7.X.Trình kích hoạt so với sự kiện JPA

Trong thực thể của tôi, tôi có một số ngày như ngày cập nhật cuối cùng:

@Column(name = "last_update_date", insertable = false, updatable = false) 
@Temporal(TemporalType.TIMESTAMP) 
private Date lastUpdateDate; 

Đối với thời điểm hiện tại tôi có một kích hoạt mà cập nhật:

CREATE TRIGGER upd_site BEFORE UPDATE ON site 
FOR EACH ROW SET NEW.last_update_date = CURRENT_TIMESTAMP(); 

Nó hoạt động tốt, nhưng tôi chỉ nhận thấy rằng có là một số phương thức gọi lại trong JPA http://www.objectdb.com/java/jpa/persistence/event

Điều gì là tốt nhất giữa các sự kiện JPA và trình kích hoạt MySql?

Cảm ơn.

Trả lời

13

Tôi đã sử dụng nó cả hai cách với Triggers trong DB và với người nghe JPA, tôi đã giải quyết trên người nghe JPA vì:

  • mã chỉ nói chuyện với cơ sở dữ liệu trong mã JPA vì vậy tôi don' t phải lo lắng về các lĩnh vực tem thời gian rơi ra khỏi ngày. (Nếu điều này thay đổi trong tương lai, tôi có thể thêm trình kích hoạt và thay đổi các siêu kết nối được ánh xạ của tôi)

  • Trình nghe JPA kém phức tạp hơn vì tôi không phải tạo nhiều bộ kích hoạt trong cơ sở dữ liệu của mình để duy trì. Kể từ khi tôi đang tích cực phát triển và thay đổi cấu trúc db khi tôi đi cùng tuyệt vời của nó không phải đi và cập nhật kích hoạt như tôi nhanh chóng lặp đi lặp lại thông qua sự phát triển.

  • Tôi có toàn quyền kiểm soát cơ sở dữ liệu và thực hiện quy tắc cho db rằng mỗi bảng sẽ có một số nguyên pkey và phiên bản số nguyên và các bảng được đóng dấu thời gian sẽ có các cột insert_tsupdate_ts. quy tắc trong thiết kế db của tôi để cuộc sống dễ dàng tôi có hai superclases ánh xạ mà làm cho tất cả enitites của tôi đơn giản để mã kể từ khi tôi mở rộng từ họ.

@MappedSuperclass 
public abstract class PersistableObject { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="pkey") 
    private Integer pkey; 

    @Version 
    @Column(name="version") 
    private Integer version; 

    public Integer getPkey() { 
     return this.pkey; 
    } 

    public Integer getVersion() { 
     return this.version; 
    } 

    @Override 
    public String toString() { 
     return "Presistable Object: pkey=" + this.pkey + " Object: " + this.getClass().getName(); 
    } 
} 

@MappedSuperclass 
public class TimeStampedPersistableObject extends PersistableObject { 

    @Column(name = "insert_ts") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date insertTimestamp; 

    @Column(name = "update_ts") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date updateTimestamp; 

    @SuppressWarnings("unused") 
    @PrePersist 
    private void onInsert() { 
     this.insertTimestamp = new Date(); 
     this.updateTimestamp = this.insertTimestamp; 
    } 

    @SuppressWarnings("unused") 
    @PreUpdate 
    private void onUpdate() { 
     this.updateTimestamp = new Date(); 
    } 


    public Date getInsertTimestamp() { 
     return this.insertTimestamp; 
    } 


    public Date getUpdateTimestamp() { 
     return this.updateTimestamp; 
    } 
} 
+3

Vấn đề duy nhất với các sự kiện JPA là gì nếu bạn muốn cập nhật db với SQL? Điều này sẽ bỏ qua các sự kiện JPA.Nói chung, db phải là tự trị và do đó các DBA sẽ cho bạn biết sử dụng các trình kích hoạt. Các nhà phát triển sẽ thích các sự kiện JPA. –

18

Không có điều tốt nhất. Trình kích hoạt cơ sở dữ liệu sẽ cập nhật ngày cập nhật cuối cùng tại mọi cập nhật của một hàng, bất kể cách được sử dụng để cập nhật hàng (Hibernate, truy vấn JDBC hoặc cập nhật từ công cụ quản trị cơ sở dữ liệu của bạn). Một cuộc gọi lại JPA sẽ chỉ được gọi khi hàng được cập nhật bằng cách sử dụng JPA. Bạn có thể muốn cái này hay cái kia.

Một điểm khác biệt là JPA không biết về trình kích hoạt được thực thi bởi cơ sở dữ liệu. Vì vậy, nếu bạn cập nhật một số trường trong thực thể của mình và JPA đã xóa thay đổi, ngày cập nhật sẽ được sửa đổi bởi trình kích hoạt, nhưng thực thể JPA sẽ giữ giá trị cũ của ngày cập nhật trong bộ nhớ. Vì vậy, nếu ngày cập nhật này được hiển thị trong GUI sau khi cập nhật, ngày cập nhật sẽ không chính xác. Bạn sẽ phải làm mới thực thể để có được ngày cập nhật mới nhất.

+1

Các bình luận trong đoạn thứ 2 là rất hữu ích. –

+0

Bộ hoàn hảo ngắn gọn khác biệt giữa trình kích hoạt cơ sở dữ liệu và phương thức gọi lại JPA. Một công việc cron cũng là một lựa chọn tốt nếu trường hợp sử dụng của bạn yêu cầu như vậy. – HopeKing

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