2016-06-13 17 views
1

我遇到了一個問題,我正在更新ebean中的模型,但其他模型引用未被更改。 我想知道是否可以使用連接列或@ManyToMany映射自動更新或刷新任何引用更新模型的模型。如何更新ebean orm中的所有引用

這是我的測試代碼:

// Create students and club 
Student john = new Student("John"); 
Student lizz = new Student("Lizz"); 
Club soccer = new Club("Soccer"); 

// Save the students 
server.save(john); 
server.save(lizz); 

// Add them to their club 
john.getClubs().add(soccer); 
server.save(john); 
lizz.getClubs().add(soccer); 
server.save(lizz); 

// Reload users (fresh) 
john = server.find(Student.class).where().ieq("name", "john").findUnique(); 
lizz = server.find(Student.class).where().ieq("name", "lizz").findUnique(); 
System.out.println("Club: " + lizz.getClubs().get(0).getName()); 

// Modify the club name 
john.getClubs().get(0).setName("Baseball"); 
System.out.println("Club: " + lizz.getClubs().get(0).getName()); 

// Update the club 
server.save(john); 
System.out.println("Club: " + lizz.getClubs().get(0).getName()); 

,這些都是我的模型:

@Entity 
@Table(name = "students") 
public class Student { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(unique = true, updatable = false) 
    private int id; 

    @Column 
    private String name; 

    @ManyToMany(mappedBy = "students", cascade = CascadeType.ALL) 
    private List<Club> clubs; 

    @Version 
    private long version; 
} 

和:

@Entity 
@Table(name = "clubs") 
public class Club { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(unique = true, updatable = false) 
    private int id; 

    @Column 
    private String name; 

    @ManyToMany 
    @JoinColumn 
    private List<Student> students; 

    @Version 
    private long version; 
} 

輸出是俱樂部仍然是足球,像這樣:
俱樂部:足球
俱樂部:足球
俱樂部:足球

+0

當代碼重新加載john和lizz ...因爲沒有跨越事務/持久性上下文...這創建了2個獨立的對象圖。這些對象圖代表「在某個時間點和某個隔離級別的數據庫部分的快照」(根據JPA規範默認讀取提交) –

+0

@RobBygrave有道理,我將隔離級別設置爲SERIALIZABLE,因爲它同時支持SQLite和MySQL,其他一些不支持 是否可以始終保持相同的引用? – lenis0012

+0

在SERIALIZABLE開放式併發檢查不起作用(當然,檢查是相對於事務的開始)。一般來說,你需要開始在SERIALIZABLE上使用悲觀鎖定,對於併發性高的應用程序來說,這是一個問題,所以READ_COMMITTED是一個非常好的選擇,除非... –

回答

2

您正在修改約翰,但打印Lizz。 Lizz沒有改變(因爲Lizz的俱樂部已經被裝載並且沒有刷新)。

原因是因爲John和Lizz的提取屬於2個不同的事務,因此有2個不同的持久化上下文。

如果發生跨越John和Lizz BOTH的交易,那麼該俱樂部對於兩者來說都是相同/單一的實例,因爲底層持久化上下文被限制在交易範圍內並且確保他們對俱樂部使用相同的實例。

作爲一個邊點你應該看看打開SQL和事務日誌,這樣你確認它做什麼,你認爲它應該:

<!-- LOGBACK configuration --> 

<!-- SQL and bind values --> 
<logger name="org.avaje.ebean.SQL" level="TRACE"/> 

<!-- Transaction Commit and Rollback events --> 
<logger name="org.avaje.ebean.TXN" level="TRACE"/> 

對於日誌配置是指http://ebean-orm.github.io/docs/setup/logging

務必:

server.beginTransaction(); 
try { 
    // persistence context scoped to transaction so 
    // .. now spans both fetches giving John and Lizz 
    // .. the same shared Club instance 
    john = server.find(Student.class).where().ieq("name", "john").findUnique(); 
    lizz = server.find(Student.class).where().ieq("name", "lizz").findUnique(); 
} finally { 
    server.endTransaction(); 
} 
+0

非常感謝您的幫助。 但是,實際上我不會同時加載它們。 但我想改變一個學生的俱樂部,而不是所有的俱樂部不一致。 – lenis0012

+0

請參閱上面的其他討論。 –

+0

僅供參考:有一段視頻在https://youtu.be/Y18HsBkeLuk上討論了Ebean的「持久性上下文」......將其與JPA進行比較,並希望解釋一下爲什麼它會像這樣工作。 –

相關問題