Java 如何更新ebean orm中的所有引用

Java 如何更新ebean orm中的所有引用,java,orm,mapping,ebean,Java,Orm,Mapping,Ebean,我在ebean中更新模型时遇到了一个问题,但是对该模型的其他引用没有被更改。 我想知道是否可以使用连接列或@manytoman映射自动更新或刷新引用更新模型的任何模型 这是我的测试代码: // Create students and club Student john = new Student("John"); Student lizz = new Student("Lizz"); Club soccer = new Club("Soccer"); // Save the students

我在ebean中更新模型时遇到了一个问题,但是对该模型的其他引用没有被更改。 我想知道是否可以使用连接列或@manytoman映射自动更新或刷新引用更新模型的任何模型

这是我的测试代码:

// 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;
}
@实体
@表(name=“学生”)
公立班学生{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(unique=true,updateable=false)
私有int-id;
@纵队
私有字符串名称;
@许多(mappedBy=“students”,cascade=CascadeType.ALL)
私人名单俱乐部;
@版本
私人长版;
}
以及:

@实体
@表(name=“俱乐部”)
公共班级俱乐部{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(unique=true,updateable=false)
私有int-id;
@纵队
私有字符串名称;
@许多
@连接柱
私人名单学生;
@版本
私人长版;
}
结果是俱乐部仍然是足球,就像这样:
俱乐部:足球
俱乐部:足球

俱乐部:足球

你在修改约翰,但在打印利兹。Lizz没有更改(因为Lizz的俱乐部已加载且未刷新)

原因是John和Lizz的获取在两个不同的事务中,因此具有两个不同的持久性上下文

如果有一个事务跨越了John和Lizz的获取,那么Club将是这两者的同一个/单个实例,因为底层持久性上下文的作用域是该事务,并确保它们为Club使用相同的实例

作为一个补充,您应该考虑启用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"/> 

当代码重新加载john和lizz时。。。由于没有跨事务/持久性上下文。。。这将创建两个独立的对象图。这些对象图表示“在某个时间点和某个隔离级别(根据JPA规范等,默认情况下读取并提交)的数据库部分快照”.@RobBygrave这很有意义,我将隔离级别设置为SERIALIZABLE,因为它同时支持SQLite和MySQL,其他一些人不可能始终保持相同的引用?在SERIALIZABLE,乐观并发检查不起作用(嗯,检查是相对于事务的开始)。一般来说,您需要在SERIALIZABLE上开始使用悲观锁定。对于具有高并发性的应用程序,这是一个问题。因此,READ_COMMITTED是一个更好的选择。除非……除非您在移动设备上等。在移动设备上,您可以将……作为SQLite的替代方案(而不是使用ORM)。”是否可以始终保持相同的引用?“…在高并发情况下,情况并非如此(不适用于ORM,也不适用于数据库)。如果您使用的是MVCC数据库,则它没有对逻辑行的单个引用,而是可以有多个引用(该行的版本,并基于事务隔离级别和事务开始时间,您可以获得该行的适当版本)。在我看来,MVCC体系结构现在是高并发应用程序最主要的体系结构(读卡器不阻止写入器,写入器不阻止读卡器)…谢谢,这非常有帮助。但是,在实践中,我不会同时加载这两个。但我想为一个学生更改俱乐部,而不会使所有俱乐部不一致。请参阅上面的其他讨论。仅供参考:有一个视频讨论Eben的“持久性上下文”“在……将其与JPA进行比较,并希望能进一步解释为什么会这样。
<!-- 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"/> 
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();
}