2014-02-24 30 views
0

基于第二种方法answered here我设计了我的JPA类。JPA,如何查找具有复合标识的对象?

@Entity(name = "SearchKeywordJPA") 
@IdClass(SearchKeywordJPA.SearchKeyId.class) 
public class SearchKeywordJPA implements Comparable<SearchKeywordJPA> { 

    @Id 
    private String keyword; 
    @Id 
    private long date; 
    private String userUUID; 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     SearchKeywordJPA that = (SearchKeywordJPA) o; 

     if (date != that.date) return false; 
     if (!keyword.equals(that.keyword)) return false; 
     if (!userUUID.equals(that.userUUID)) return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     int result = keyword.hashCode(); 
     result = 31 * result + (int) (date^(date >>> 32)); 
     result = 31 * result + userUUID.hashCode(); 
     return result; 
    } 

    @Override 
    public String toString() { 
     return "SearchKeywordJPA{" + 
       "keyword='" + keyword + '\'' + 
       ", date=" + date + 
       ", userUUID='" + userUUID + '\'' + 
       '}'; 
    } 

    public String getKeyword() { 
     return keyword; 
    } 

    public void setKeyword(String keyword) { 
     this.keyword = keyword; 
    } 

    public long getDate() { 
     return date; 
    } 

    public void setDate(long date) { 
     this.date = date; 
    } 

    public String getUserUUID() { 
     return userUUID; 
    } 

    public void setUserUUID(String userUUID) { 
     this.userUUID = userUUID; 
    } 

    @Override 
    public int compareTo(SearchKeywordJPA searchRecord) { 
     long comparedDate = searchRecord.date; 

     if (this.date > comparedDate) { 
      return 1; 
     } else if (this.date == comparedDate) { 
      return 0; 
     } else { 
      return -1; 
     } 
    } 

    /********************** 
    * Key class 
    **********************/ 
    public class SearchKeyId { 
     private int id; 
     private int version; 
    } 
} 

在我的servlet中,我想检查数据存储并存储我的对象如果不存在。

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    ... 
      for(SearchKeywordJPA item: applicationList) { 
       if(!isRecorded(item)) 
        storeRecord(item); 
      } 

     } 

    private boolean isRecorded(SearchKeywordJPA record) { 
     EntityManager em = EMF.get().createEntityManager(); 

     SearchKeywordJPA item = em.find(SearchKeywordJPA.class, record); 
     return item != null; 

    } 

    private void storeRecord(SearchKeywordJPA record) { 
     EntityManager em = EMF.get().createEntityManager(); 

     em.persist(record); 
    } 

然而,当我运行,应用程序崩溃和日志说

javax.persistence.PersistenceException: org.datanucleus.store.appengine.FatalNucleusUserException: Received a request to find an object of type com.twitterjaya.model.SearchKeywordJPA identified by SearchKeywordJPA{keyword='airasia', date=1335680686149, userUUID='FFFF0000'}. This is not a valid representation of a primary key for an instance of com.twitterjaya.model.SearchKeywordJPA. 

的原因是什么?任何建议,将不胜感激。谢谢

回答

0

您将IdClass的实例传递给em.find ...即SearchKeyId。很明显,如果你真的有一个IdClass,那么你可能会遇到很多问题。这些问题只会通过使用古老的GAE/Datastore插件来增加。

0

如果你的重点是

@Entity(name = "SearchKeywordJPA") 
@IdClass(SearchKeywordJPA.SearchKeyId.class) 
public class SearchKeywordJPA implements Comparable<SearchKeywordJPA> { 

你做错了。

  1. IdClass不需要@IdClass的任何注释只是@Id 注释。
  2. 密钥不能是实体。
  3. 需要实现Serializable,可比不需要
  4. 需要重写equals和hascode,没有参数的构造函数

类重点需要如下。

public class SearchKeyId implements Serializable { 

    private String keyword; 

    private long date; 

而你的实体我假设这样。

@Entity(name = "SearchKeywordJPA") 
@IdClass(SearchKeyId.class) 
public class SearchKeywordJPA { 
    @Id 
    private String keyword; 
    @Id 
    private long date; 

    private String userUUID; 
  • 就认为找到方法将使用SearchKey.class找到 的实体。
  • IdClass中的字段需要在实体中有@Id注释。
  • 密钥不能是一个实体。
  • 可比是不是真的需要,因为所有的比较都放在一个IdClass的IdClass
+2

字段*不*需要进行注释。这是一个“ID”,所以IdClass的所有字段都是ID的一部分。 –

+0

是的我的不好,我只是复制代码,忘了那个谢谢。 – Koitoer

相关问题