2015-12-13 93 views
3

我有我的查詢返回的陳舊的數據庫中的數據的麻煩,所以我認爲它會是與緩存。我完全不明白是怎麼回事,我很樂意。緩存在JPA(EclipseLink的+ Dropwizard + MySQL的)

我必須映射到實體的數據庫表中的應用:

@Entity 
@Table(name = "app_application", catalog = "something", schema = "") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "Application.findById", 
    query = "SELECT a FROM Application a WHERE a.id = :id")) 
    } 
) 
public class Application implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "id") 
    private Integer id; 

    ... 

    @JoinColumn(name = "status", referencedColumnName = "id") 
    @ManyToOne(optional = false) 
    private ApplicationStatus status; 

    .... 

我也有Dropwizard實現REST服務,我獲取這些野獸:

@GET 
@Timed 
@Path("/{id}") 
public Application findById(@PathParam("id") int id) { 
    return em.find(Application.class, id); // em is an entity manager 
} 

如果我開始了我的Dropwizard應用並訪問此資源,我的應用程序會第一次正確返回。然後,如果我去到數據庫,並手動更改從「接受」到「拒絕」(外鍵)應用狀態值,並再次訪問我的REST服務獲取相同的應用程序,它不更新的狀態屬性(我手動數據庫更改被忽略)。如果我把整個事情並重新啓動,REST服務獲取更新後的值並正確返回實體(直到我再次手動修改數據庫)。

這裏是我的執着單位:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
<persistence-unit name="to.rented_RentedToPMS_jar_1.0-SNAPSHOTPU" transaction-type="RESOURCE_LOCAL"> 
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
<class>pms.core.entities.applications.Application</class> 
<class>pms.core.entities.applications.ApplicationStatus</class> 
<properties> 
    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/rented?zeroDateTimeBehavior=convertToNull"/> 
    <property name="javax.persistence.jdbc.user" value="someuser"/> 
    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 
    <property name="javax.persistence.jdbc.password" value="somepassword"/> 
</properties> 
</persistence-unit> 
</persistence> 

沒有任何結果,我想補充說:

<property name="eclipselink.query-results-cache" value="false"/> 
    <property name="eclipselink.cache.shared.default" value="false"/> 

以及使用NameQuery與提示獲取:

setHint(QueryHints.CACHE_USAGE, CacheUsage.DoNotCheckCache) 

人幫助我解釋發生了什麼?

編輯:

這似乎糾正問題。但儘管如此,這是否意味着我需要調用刷新爲每個實體?如果我想獲取所有應用程序,該怎麼辦?我是否需要遍歷它們並刷新?這似乎很愚蠢的我,所以我想答案是否定的......

@GET 
@Timed 
@Path("/noauth/{id}") 
public Application findById(@PathParam("id") int id) { 
    Application a = em.find(Application.class, id); 
    em.refresh(a); 
    return a; 
} 

回答

0

1)嘗試添加到持久化單元(更多信息請參見this):

<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> 

2)如果( 2)沒有工作,嘗試實體之前添加註釋@Cacheable(假):

... 
@Cacheable(false) 
public class Application implements Serializable { 

3)(3)不工作,em.find,運行應用程序調試模式,並設置斷點( Application.class,id)或者在這裏添加日誌記錄行,如果你的應用程序停在斷點只有第一次,有休息的問題,如果停止everytimes - 使用JPA。

更新:如果em.refresh(一)幫你,它意味着你的EntityManager不是無狀態的在你的servlet,例如它的例如無狀態:

@Stateless 
public class YourServlet { 
    @PersistenceContext EntityManager em; 

    public void enterOrder(int custID, Order newOrder) { 
     Application a = em.find(Application.class, id); 
     ... 
    } 

它是有狀態:

@Stateful 
public class YourServlet { 
    @PersistenceContext EntityManager em; 

    public void enterOrder(int custID, Order newOrder) { 
     Application a = em.find(Application.class, id); 
     ... 
    } 
+0

(1)沒有幫助,(2)沒有幫助,以及(1)和(2)沒有幫助的組合。我在em.find()之前和之後添加了日誌記錄語句。每次訪問REST時都會打印它,所以它應該是JPA。 – Martin

+0

我修復了我的帖子,它看起來像在您的servlet EntityManager中處於完好狀態,並且只能處理一個事務。您可以嘗試更改em無狀態或爲每個請求打開新的事務 –

+0

嗯,這個無狀態問題可能就是這樣,但是被告知的真相,我真的不知道如何解決它。我不知道如何將dropwizard資源變爲無狀態 - 我不清楚@Stateless註釋屬於Dropwizard架構的位置:Dropwizard建立在Jersey上。資源在應用程序啓動時與Jersey註冊。這也是我創建實體管理器的地方---我將它作爲主應用程序類的靜態屬性,並在資源類中使用靜態獲取器進行檢索。這種做法是絕對錯誤的嗎? – Martin