2011-08-23 27 views
5

Tôi đang di chuyển một ứng dụng từ cấu hình xml ngủ đông sang chú thích, tôi không chắc chắn cách điều chỉnh lớp BusinessObjectInterceptor của tôi thành định dạng dựa trên chú thích mới.Hibernate Interceptors with Annotations

Chúng tôi đang thay đổi lớp HibernateUtil của chúng tôi từ việc tạo SessionFactory

  InitialContext ctx  = new InitialContext(); 
     sessionFactory = (SessionFactory)ctx.lookup("java:/hibernate/SessionFactory"); 

để tạo EntityManagerFactory

  entityManagerFactory = Persistence.createEntityManagerFactory("primary"); 

Chúng tôi đang thay đổi lớp HibernateUtil của chúng tôi từ việc sử dụng sessionFactory.openSession() để tạo ra một phiên từ một EntityManager

  //s = sessionFactory.openSession(new BusinessObjectInterceptor()); 
     EntityManager entityManager = entityManagerFactory.createEntityManager(); 
     s = entityManager.unwrap(Session.class); 

Vấn đề tôi s Tôi không chắc chắn làm thế nào để tiêm một BusinessObjectInterceptor vào một phiên Hibernate mới, hoặc cách thích hợp để chú thích các lớp học của tôi để họ có thể sử dụng Interceptor

Tôi đang cố gắng đặt Interceptor làm tài sản trong trạng thái kiên trì. xml. Tôi không chắc chắn nếu điều này là đúng

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" 
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"> 
    <persistence-unit name="primary"><jta-data-source>java:jboss/datasources/MySqlDS</jta-data-source> 

    <properties> 
    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> 
    <property name="hibernate.ejb.interceptor.session_scoped" value="com.mycompany.common.persistence.BusinessObjectInterceptor"/> 
      </properties> 

lớp của chúng tôi đã được cấu hình từ trước thông qua file hbm.xml

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping> 
    <class name="com.mycompany.liveexpert.common.businessobjects.ServerSettings" table="server_settings"> 
      <id name="serverSettingsID" type="integer" column="server_settings_id"> 
        <generator class="identity" /> 
      </id> 
      <version name="updateCounter" column="update_counter"/> 
      <property name="changedDate" type="timestamp" column="changed_date"/> 
      <property name="changedBy" type="string" column="changed_by"/> 
      <property name="createdDate" type="timestamp" column="created_date"/> 
      <property name="createdBy" type="string" column="created_by"/> 
      <property name="status" type="string" column="status"/> 

      <property name="emailServer" type="string" column="email_server" /> 
      <property name="emailFromAddress" type="string" column="email_from_address" /> 
      <property name="emailUser" type="string" column="email_user" /> 
      <property name="emailPassword" type="string" column="email_password" /> 

</class> 

các lớp chú trông giống như

@Entity 
@Table(name="server_settings") 
public class ServerSettings extends BusinessObject 
{ 
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Integer serverSettingsID; 
    @Column(name = "email_server") 
    private String emailServer; 
    @Column(name = "email_from_address") 
private String emailFromAddress; 
    @Column(name = "email_user") 
private String emailUser; 
    @Column(name = "email_password") 
private String emailPassword; 

Chúng ta có một lớp BusinessObjectInterceptor và một lớp BusinessObject. Tôi sẽ gửi chúng dưới đây để tham khảo. Tôi nghĩ rằng những gì cần phải xảy ra là lớp BusinessObject cần được chú thích, tôi không chắc chắn cách thực hiện vì BusinessObject không ánh xạ tới các cột trong một bảng cụ thể, mà là các cột chung cho tất cả các bảng trong cơ sở dữ liệu của chúng tôi. Tôi sẽ dán hai lớp này bên dưới. Bất kỳ lời khuyên nào về cách thiết lập Interceptor của tôi với chú thích sẽ được đánh giá cao. Cảm ơn.

BusinessObjectInterceptor

public class BusinessObjectInterceptor extends EmptyInterceptor 
{ 
private int updates; 
private int creates; 

private static final String defaultDesignation = "system"; 

private String getUserDesignation() 
{ 
    UserContextI theContext = PersistenceContext.getUserContext(); 
    if (theContext == null) return defaultDesignation; 
    String uid = theContext.getUserDesignation(); 
    if (uid == null) return defaultDesignation; 
    return uid; 
} 
public boolean onFlushDirty(Object entity, 
          Serializable id, 
          Object[] currentState, 
          Object[] previousState, 
          String[] propertyNames, 
          Type[] types) 
{ 
    boolean theReturn = false; 
    if (entity instanceof BusinessObject) 
    { 
     updates++; 
     for (int i=0; i<propertyNames.length; i++) 
     { 
      if ("changedDate".equals(propertyNames[i])) 
      { 
       currentState[i] = new Date(); 
       theReturn = true; 
      } 
      if ("changedBy".equals(propertyNames[i])) 
      { 
       currentState[i] = getUserDesignation(); 
       theReturn = true; 
      } 
     } 
    } 
    return theReturn; 
} 
public boolean onSave(Object entity, 
     Serializable id, 
     Object[] state, 
     String[] propertyNames, 
     Type[] types) 
{ 
    boolean theReturn = false; 
    if (entity instanceof BusinessObject) 
    { 
     creates++; 
     for (int i=0; i<propertyNames.length; i++) 
     { 
      if ("createdDate".equals(propertyNames[i])) 
      { 
       state[i] = new Date(); 
       theReturn = true; 
      } 
      if ("createdBy".equals(propertyNames[i])) 
      { 
       state[i] = getUserDesignation(); 
       theReturn = true; 
      } 
      if ("changedDate".equals(propertyNames[i])) 
      { 
       state[i] = new Date(); 
       theReturn = true; 
      } 
      if ("changedBy".equals(propertyNames[i])) 
      { 
       state[i] = getUserDesignation(); 
       theReturn = true; 
      } 
     } 
    } 
    return theReturn; 
} 
public void preFlush(Iterator entities) 
{ 
    updates = 0; 
    creates = 0; 
} 

BusinessObject

public abstract class BusinessObject 
{ 
private String status; 
private String createdBy; 
private Date createdDate; 
private String changedBy; 
private Date changedDate; 
private int updateCounter; 

/** 
* Generic save method to be used for persisting a business object. 
* 
* @return a copy of this business object in its saved state. 
* 
* @throws Exception 
*/ 
public BusinessObject save() throws Exception 
{ 
    Session  hsession = null; 
    Transaction tx = null; 
    BusinessObject theObject = null; 

    validate(); // throws ValidationException 

    try { 
     hsession = HibernateUtil.currentSession(); 
     tx = hsession.beginTransaction(); 

     if (getStatus() == null || getStatus().length() < 1) 
     { 
      setStatus("OK"); 
     } 

     //theObject = (BusinessObject) hsession.saveOrUpdateCopy(this); 
     theObject = (BusinessObject) hsession.merge(this); 
     if (tx != null && tx.isActive() && !tx.wasCommitted()) 
      tx.commit(); 
    } catch (Exception e){ 
     try 
     { 
     if (tx!=null) tx.rollback(); 
     } catch (Exception e3) 
     {} 
     try 
     { 
     hsession.close(); 
     } catch (Exception e2) 
     {} 
     throw e; 
    } finally 
    { 
     HibernateUtil.closeSession(); 
    } 
    return theObject; 
} 
+0

bản sao có thể có của [Sử dụng chú thích mùa xuân để tự động áp dụng Bộ chặn đánh chặn Hibernate?] (Http://stackoverflow.com/questions/2132151/use-spring-annotations-to-automatically-apply-hibernate-interceptor) –

+0

Có thể có một số thông tin trong q đó uestion có thể giúp tôi, nhưng tôi không sử dụng Spring nên nó không hoàn toàn áp dụng được. – user619804

+0

Ok.Tôi không thể rút lại phiếu bầu của tôi, nhưng nếu nó đóng cửa, tôi sẽ bỏ phiếu để trả lại. –

Trả lời

2

Trong JPA bạn có thể sử dụng @PrePersist@PreUpdate chú thích để chú thích một phương pháp trong mô hình của bạn (@Entity class) mà sẽ được gọi trước khi sự bền bỉ (INSERT) hoặc cập nhật (UPDATE).

Bạn có thể tạo một người biết lắng nghe thực thể, và thêm @EntityListeners chú thích để mô hình của bạn, như:

public class BusinessListener { 
    @PrePersist 
    public void businessUpdate(BusinessObject obj) { 
     obj.setCreatedDate(new Date()); 
     .... 
    } 
    @PreUpdate 
    public void businessUpdate(BusinessObject obj) { 
     obj.setChangedDate(new Date()); 
     .... 
    } 
} 

@EntityListeners(class=...BusinessListener) 
public class BusinessObject { 
} 

Hoặc bạn có thể đặt các phương thức trong một lớp thực thể cơ sở và mở rộng tất cả các đơn vị của bạn từ nó, như:

public class BusinessObject { 
    @PrePersist 
    public void businessUpdate() { 
     createdDate = new Date(); 
     .... 
    } 
    @PreUpdate 
    public void businessUpdate() { 
     changedDate = new Date(); 
     .... 
    } 
} 
+1

Đó không phải là chính xác như nhau. I E. vào 'EmptyInterceptor # onDirtyFlush' bạn có thể vượt qua trạng thái thực thể trước đó/hiện tại. Nhưng '@ PreUpdate' hoặc' @ EntityListener' chỉ có thể cho bạn biết trạng thái hiện tại. Ý tôi là những kẻ đánh chặn vẫn mạnh hơn những người bạn được chú thích của họ –