我有我的问题的简单例子。有两个学生和三个科目。起初,学生1拥有所有科目,学生2没有科目。关系是一个学生和多个学科的关系。
我正在尝试使用jpa hibernate将subject1从学生1交换到学生2。在数据库中出现事务提交更改后:主题表的外键student_id发生了更改,但在java中,即使我从数据库加载学生1,对象仍然具有subject1。
@Entity
@Table(name = "STUDENTS")
public class Students {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ST_ID")
private int id;
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
List<Subject> subjects = new ArrayList<>();
//getters and setters....
}
@Entity
@Table(name = "SUBJECT")
public class Subject {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "SB_ID")
private int id;
@Column(name = "MARK")
private int mark;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "ST_ID")
private Students student;
//getters and setter....
}
主要代码:
public static void main(String[] args) throws Exception {
EntityManager em = Persistence.createEntityManagerFactory("Test").createEntityManager();
// em.getTransaction().begin(); //does not work
Students student1 = getStudentById(1, em); //load student1 from database by id
Students student2 = getStudentById(2, em); //load student2 from database by id
Subject subject1 = getSubjectById(1, em); //load subject1 from database by id
Subject subject2 = getSubjectById(2, em); //load subject2 from database by id
Subject subject3 = getSubjectById(3, em); //load subject3 from database by id
System.out.println("student1 subjects");
for(Subject sb : student1.getSubjects()){
System.out.println(sb.getId()); //prints subjects: 1,2,3
}
System.out.println("\nstudent2 subjects");
for(Subject sb : student2.getSubjects()){
System.out.println(sb.getId()); //prints no subjects
}
//swap subject1 between student1 and student2
subject1.setStudent(student2);
student2.getSubjects().add(subject1);
//save changes
em.getTransaction().begin();
em.persist(student2);
em.persist(student1);
em.persist(subject2);
em.persist(subject1);
//em.merge does't work
//em.flush(); //doesn't work
em.getTransaction().commit();
student1 = getStudentById(1, em); //load student1 from database by id
System.out.println("\nstudent1 subjects");
for(Subject sb : student1.getSubjects()){
System.out.println(sb.getId()); //and still student1 has subject1
}
student2 = getStudentById(2, em); //load student2 from databse by id
System.out.println("\nstudent2 subjects");
for(Subject sb : student2.getSubjects()){
System.out.println(sb.getId()); //now student2 also has subject1
}
}
public static Students getStudentById(int id, EntityManager em){
Query query = em.createQuery("from entity.Students where ST_ID="+id);
return (Students)query.getSingleResult();
}
public static Subject getSubjectById(int id, EntityManager em){
Query query = em.createQuery("from entity.Subject where SB_ID="+id);
return (Subject) query.getSingleResult();
}
提交后主题表如下所示。它显示id为1的科目现在有id为2的学生。
只有在提交后进行em.refresh时,实体对象student1才会更新,但我不明白为什么从数据库加载student1时需要使用refresh?而且我也不确定,刷新实体是一种好的做法吗?
您必须了解,如果可能的话,Hibernate会从一级缓存或持久性上下文返回对象,以保留对象标识。因此,即使使用查询从数据库中加载学生,它也只会返回之前持久化的对象,因为它与持久化上下文关联。
当您想从数据库中重新加载状态时,您必须使用刷新
或分离
,然后执行查询。
我目前正在重构遗留代码,以使用Android架构组件,并在一种存储库模式中设置一个房间数据库和截取请求。因此,表示层/域层要求存储库获取LiveData对象进行观察,或告诉他与服务器同步,然后删除旧的db条目,并从服务器中重新提取所有当前条目。 我已经写了同步部分的测试,所以我确信,对象被正确地获取并插入到数据库中。但是当写一个测试来观察db表的条目时(并测试对象是否被正确保存,以及在将它们放入d
我想知道ehcache是否有办法检测数据库更新/插入(spring/java,hibernate web应用程序),并使用数据库中的当前(最新)数据刷新其缓存。如果没有,检测数据库更新的最佳方法是什么,以保持与缓存和数据库之间的数据同步?
问题内容: 我将一些对象存储在切片中。在将其附加到切片之前,我先打印对象的名称。 将其存储在切片中之后,我将其检索为指针,并希望将名称更改为,但是更改仍然有效,因为它仍然可以打印。为什么? 问题答案: 每当方法想要修改接收者时, 它都必须是指向该值的指针 ;该方法必须具有指针接收器。 如果方法具有非指针接收者,则在调用该方法时将创建并传递一个副本。从那时起,无论您对接收器做什么,都只能修改副本,而
问题内容: 我有必须转换为JSON的Hibernate实体,并且必须转换实体中的某些值,但是当我转换值时,这些值会立即保存到数据库中,但是我不想将这些更改保存到数据库中。有没有解决此问题的方法? 问题答案: 您可以通过调用分离实体。 其他选择是在转换值之前为您的实体创建防御性副本,或者在该代码中使用DTO代替该实体。我认为这些选项更优雅,因为它们不将转换转换为JSON和持久层。
问题内容: 在启动时如何从数据库表中加载规则并从Drools 6.2.0中的同一表中更新规则呢?我找到了一个使用Drools 5 的示例,我可能可以将它从Scala转换为Java,但看起来API发生了巨大变化……例如,我看不到RuleBaseFactory类。 任何样品或文件将不胜感激。 问题答案: 我不确定从哪儿拿来的。以下是在Drools 5.3(可能更早)至5.6中的完成方式: 省略号指示用
我在我的GAE数据存储实验中发现了一些很奇怪的东西。我使用的是GAE SDK 1.7.5。我不确定我的发现是否正确。 基本上,我发现在执行数据存储get之前,将实体放入数据存储并进行计数不会返回正确的值。 如果你想更深入地挖掘,这里是我前面的SO问题中的实际代码: