遇到一个奇怪问题,数据已经保存至数据库,但entityManager.find却取不到数据,重启tomcat后,entityManager.find又可以取到数据,不知道大家是否遇到过?
1.mysql数据库,表如下:CREATE TABLE `school` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(10) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
);CREATE TABLE `course` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ;CREATE TABLE `student` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(10) NOT NULL DEFAULT '',
`school_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);CREATE TABLE `student_course` (
`stu_id` int(10) NOT NULL,
`cos_id` int(10) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `stu_id` (`stu_id`,`cos_id`),
KEY `student_course_fk_cosId` (`cos_id`),
CONSTRAINT `student_course_fk_stuId` FOREIGN KEY (`stu_id`) REFERENCES `student` (`id`),
CONSTRAINT `student_course_fk_cosId` FOREIGN KEY (`cos_id`) REFERENCES `course` (`id`)
);
2.Java代码如下
采用spring 3 + struts2 + openjpa框架, Dao通过spring注入@Component
public class TestDao extends ActionSupport {
private static final long serialVersionUID = 1L;
@Resource(name="studentDao")
private IBaseDao<Student> stuDao;
@Resource(name="schoolDao")
private IBaseDao<School> schDao;
@Resource(name="courseDao")
private IBaseDao<Course> cosDao;
@Resource(name="studentCourseDao")
private IBaseDao<StudentCourse> stuCosDao;
@Override
public String execute() {
System.out.println("Called!!");
testSchCRUD();
//testQuery();
return SUCCESS;
}
public void testQuery() {
Student stu = stuDao.findByName("stu-1");
showStudent(stu);
}
public void testSchCRUD() {
// add school
School sch = new School();
sch.setName("school");
schDao.save(sch);
// add courses
Course cos = new Course();
cos.setName("Math");
cosDao.save(cos);
cos = new Course();
cos.setName("Computer");
cosDao.save(cos);
cos = new Course();
cos.setName("English");
cosDao.save(cos);
// add students
Student stu = new Student();
stu.setName("stu-1");
stuDao.save(stu);
stu = new Student();
stu.setName("stu-2");
stuDao.save(stu);
// add students to school
School sch = schDao.findByName("school");
Student stu = stuDao.findByName("stu-1");
stu.setSchool(sch);
stuDao.save(stu);
showSchool(schDao.findByName("school"));
// student select courses
stu = stuDao.findByName("stu-1");
Course cos = cosDao.findByName("Math");
StudentCourse stuCos = new StudentCourse();
stuCos.setCourse(cos);
stuCos.setStudent(stu);
stuCosDao.save(stuCos);
showSchool(schDao.findByName("school"));
}
private void showSchool(School sch) {
if (null != sch) {
System.out.println("School Name:" + sch.getName());
System.out.println("Students:\nNo.\tName");
List<Student> stuList = sch.getStudents();
if (null != stuList && stuList.size() > 0) {
int index = 1;
for (Student stuIter : stuList) {
System.out.print(index + "\t");
showStudent(stuIter);
index++;
}
}
} else {
System.out.println("No School Data!!");
}
} private void showStudent(Student stu) {
if (null != stu) {
System.out.println(stu.getName());
int index = 1;
Set<StudentCourse> stuCosSet = stu.getStudentCourses();
if (stuCosSet != null && stuCosSet.size() > 0) {
System.out.println("\tCourses:");
for (StudentCourse stuCos : stuCosSet) {
System.out.printf("\t%d\t%s\n", index, stuCos.getCourse().getName());
index++;
}
}
} else {
System.out.println("No Student Data!!");
}
} public void setSchDao(SchoolDao schDao) {
this.schDao = schDao;
}
public void setStuDao(StudentDao stuDao) {
this.stuDao = stuDao;
} public void setCosDao(IBaseDao<Course> cosDao) {
this.cosDao = cosDao;
} public void setStuCosDao(IBaseDao<StudentCourse> stuCosDao) {
this.stuCosDao = stuCosDao;
}
}
package com.test.dao;
public interface IBaseDao<T> {
int save(T o);
T find(int id);
void remove(int id);
T findByName(String name);
}
@Repository
@Transactional
public class StudentDao implements IBaseDao<Student>{
@PersistenceContext
private EntityManager em;
@Override
public int save(Student stu) {
if (0 == stu.getId()) {
em.persist(stu);
} else {
em.merge(stu);
}
return stu.getId();
}
@Override
public void remove(int id) {
Student stu = em.find(Student.class, id);
if (stu != null) {
em.remove(stu);
}
}
@Override
public Student find(int id) {
Student stu = em.find(Student.class, id);
em.refresh(stu);
return stu;
}
@Override
public Student findByName(String name) {
Query query = em.createQuery("select stu from Student stu where stu.name = ?1");
query.setParameter(1, name);
query.setMaxResults(1);
return (Student) query.getSingleResult();
}
}
@Component
@Transactional
public class StudentCourseDao implements IBaseDao<StudentCourse> { @PersistenceContext
private EntityManager em;
@Override
public int save(StudentCourse o) {
// TODO Auto-generated method stub
if (0 == o.getId()) {
em.persist(o);
} else {
em.merge(o);
}
return o.getId();
} @Override
public StudentCourse find(int id) {
// TODO Auto-generated method stub
return em.find(StudentCourse.class, id);
} @Override
public void remove(int id) {
// TODO Auto-generated method stub
StudentCourse stuCos = em.find(StudentCourse.class, id);
if (stuCos != null) {
em.remove(stuCos);
}
} @Override
public StudentCourse findByName(String name) {
// TODO Auto-generated method stub
return null;
}}
@Repository
@Transactional
public class SchoolDao implements IBaseDao<School>{
@PersistenceContext
private EntityManager em;
@Override
public int save(School school) {
if (0 == school.getId()) {
em.persist(school);
} else {
em.merge(school);
}
return school.getId();
}
@Override
public void remove(int id) {
School sch = em.find(School.class, id);
if (sch != null) {
em.remove(sch);
}
}
@Override
public School find(int id) {
return em.find(School.class, id);
} @Override
public School findByName(String name) {
// TODO Auto-generated method stub
Query query = em.createQuery("select s from School s where s.name = ?1");
query.setParameter(1, name);
query.setMaxResults(1);
return (School) query.getSingleResult();
}
}
@Component
@Transactional
public class CourseDao implements IBaseDao<Course> { @PersistenceContext
private EntityManager em;
@Override
public int save(Course o) {
// TODO Auto-generated method stub
if (0 == o.getId()) {
em.persist(o);
} else {
em.merge(o);
}
return o.getId();
} @Override
public Course find(int id) {
// TODO Auto-generated method stub
return em.find(Course.class, id);
} @Override
public void remove(int id) {
// TODO Auto-generated method stub
Course cos = find(id);
if (null != cos) {
em.remove(cos);
}
}
public Course findByName(String name) {
Query query = em.createQuery("select c from Course c where c.name = ?1");
query.setParameter(1, name);
query.setMaxResults(1);
return (Course) query.getSingleResult();
}
}
@Entity
@Table(name="course")
public class Course implements Serializable {
private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int id; @Column(nullable=false, length=20)
private String name; //bi-directional many-to-one association to StudentCourse
@OneToMany(mappedBy="course", cascade = ALL, fetch = FetchType.EAGER)
private List<StudentCourse> studentCourses; public Course() {
} public int getId() {
return this.id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return this.name;
} public void setName(String name) {
this.name = name;
} public List<StudentCourse> getStudentCourses() {
return this.studentCourses;
} public void setStudentCourses(List<StudentCourse> studentCourses) {
this.studentCourses = studentCourses;
}
public void addStudentCourse(StudentCourse stuCos) {
if (null == this.studentCourses) {
this.studentCourses = new ArrayList<StudentCourse>();
}
this.studentCourses.add(stuCos);
}
}@Entity
@Table(name="school")
public class School implements Serializable {
private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int id; @Column(nullable=false, length=10)
private String name; //bi-directional many-to-one association to Student
@OneToMany(mappedBy="school", cascade = ALL, fetch = FetchType.EAGER)
private List<Student> students; public School() {
} public int getId() {
return this.id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return this.name;
} public void setName(String name) {
this.name = name;
} public List<Student> getStudents() {
return this.students;
} public void setStudents(List<Student> students) {
this.students = students;
}
public void addStudent(Student stu) {
if (null == this.students) {
this.students = new ArrayList<Student>();
}
this.students.add(stu);
}
}TestDao中testSchCRUD(),当给课程及学生建立联系后,通过find找不到相应的数据;如果关系的建立是通过One端类Student进行,那么find也可以找到;如果将tomcat重启,find也可以找到数据。已经被这个问题困扰很久了,急求各位找出原因。多谢!!openjpatransactionalspringmysql
1.mysql数据库,表如下:CREATE TABLE `school` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(10) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
);CREATE TABLE `course` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ;CREATE TABLE `student` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(10) NOT NULL DEFAULT '',
`school_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);CREATE TABLE `student_course` (
`stu_id` int(10) NOT NULL,
`cos_id` int(10) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `stu_id` (`stu_id`,`cos_id`),
KEY `student_course_fk_cosId` (`cos_id`),
CONSTRAINT `student_course_fk_stuId` FOREIGN KEY (`stu_id`) REFERENCES `student` (`id`),
CONSTRAINT `student_course_fk_cosId` FOREIGN KEY (`cos_id`) REFERENCES `course` (`id`)
);
2.Java代码如下
采用spring 3 + struts2 + openjpa框架, Dao通过spring注入@Component
public class TestDao extends ActionSupport {
private static final long serialVersionUID = 1L;
@Resource(name="studentDao")
private IBaseDao<Student> stuDao;
@Resource(name="schoolDao")
private IBaseDao<School> schDao;
@Resource(name="courseDao")
private IBaseDao<Course> cosDao;
@Resource(name="studentCourseDao")
private IBaseDao<StudentCourse> stuCosDao;
@Override
public String execute() {
System.out.println("Called!!");
testSchCRUD();
//testQuery();
return SUCCESS;
}
public void testQuery() {
Student stu = stuDao.findByName("stu-1");
showStudent(stu);
}
public void testSchCRUD() {
// add school
School sch = new School();
sch.setName("school");
schDao.save(sch);
// add courses
Course cos = new Course();
cos.setName("Math");
cosDao.save(cos);
cos = new Course();
cos.setName("Computer");
cosDao.save(cos);
cos = new Course();
cos.setName("English");
cosDao.save(cos);
// add students
Student stu = new Student();
stu.setName("stu-1");
stuDao.save(stu);
stu = new Student();
stu.setName("stu-2");
stuDao.save(stu);
// add students to school
School sch = schDao.findByName("school");
Student stu = stuDao.findByName("stu-1");
stu.setSchool(sch);
stuDao.save(stu);
showSchool(schDao.findByName("school"));
// student select courses
stu = stuDao.findByName("stu-1");
Course cos = cosDao.findByName("Math");
StudentCourse stuCos = new StudentCourse();
stuCos.setCourse(cos);
stuCos.setStudent(stu);
stuCosDao.save(stuCos);
showSchool(schDao.findByName("school"));
}
private void showSchool(School sch) {
if (null != sch) {
System.out.println("School Name:" + sch.getName());
System.out.println("Students:\nNo.\tName");
List<Student> stuList = sch.getStudents();
if (null != stuList && stuList.size() > 0) {
int index = 1;
for (Student stuIter : stuList) {
System.out.print(index + "\t");
showStudent(stuIter);
index++;
}
}
} else {
System.out.println("No School Data!!");
}
} private void showStudent(Student stu) {
if (null != stu) {
System.out.println(stu.getName());
int index = 1;
Set<StudentCourse> stuCosSet = stu.getStudentCourses();
if (stuCosSet != null && stuCosSet.size() > 0) {
System.out.println("\tCourses:");
for (StudentCourse stuCos : stuCosSet) {
System.out.printf("\t%d\t%s\n", index, stuCos.getCourse().getName());
index++;
}
}
} else {
System.out.println("No Student Data!!");
}
} public void setSchDao(SchoolDao schDao) {
this.schDao = schDao;
}
public void setStuDao(StudentDao stuDao) {
this.stuDao = stuDao;
} public void setCosDao(IBaseDao<Course> cosDao) {
this.cosDao = cosDao;
} public void setStuCosDao(IBaseDao<StudentCourse> stuCosDao) {
this.stuCosDao = stuCosDao;
}
}
package com.test.dao;
public interface IBaseDao<T> {
int save(T o);
T find(int id);
void remove(int id);
T findByName(String name);
}
@Repository
@Transactional
public class StudentDao implements IBaseDao<Student>{
@PersistenceContext
private EntityManager em;
@Override
public int save(Student stu) {
if (0 == stu.getId()) {
em.persist(stu);
} else {
em.merge(stu);
}
return stu.getId();
}
@Override
public void remove(int id) {
Student stu = em.find(Student.class, id);
if (stu != null) {
em.remove(stu);
}
}
@Override
public Student find(int id) {
Student stu = em.find(Student.class, id);
em.refresh(stu);
return stu;
}
@Override
public Student findByName(String name) {
Query query = em.createQuery("select stu from Student stu where stu.name = ?1");
query.setParameter(1, name);
query.setMaxResults(1);
return (Student) query.getSingleResult();
}
}
@Component
@Transactional
public class StudentCourseDao implements IBaseDao<StudentCourse> { @PersistenceContext
private EntityManager em;
@Override
public int save(StudentCourse o) {
// TODO Auto-generated method stub
if (0 == o.getId()) {
em.persist(o);
} else {
em.merge(o);
}
return o.getId();
} @Override
public StudentCourse find(int id) {
// TODO Auto-generated method stub
return em.find(StudentCourse.class, id);
} @Override
public void remove(int id) {
// TODO Auto-generated method stub
StudentCourse stuCos = em.find(StudentCourse.class, id);
if (stuCos != null) {
em.remove(stuCos);
}
} @Override
public StudentCourse findByName(String name) {
// TODO Auto-generated method stub
return null;
}}
@Repository
@Transactional
public class SchoolDao implements IBaseDao<School>{
@PersistenceContext
private EntityManager em;
@Override
public int save(School school) {
if (0 == school.getId()) {
em.persist(school);
} else {
em.merge(school);
}
return school.getId();
}
@Override
public void remove(int id) {
School sch = em.find(School.class, id);
if (sch != null) {
em.remove(sch);
}
}
@Override
public School find(int id) {
return em.find(School.class, id);
} @Override
public School findByName(String name) {
// TODO Auto-generated method stub
Query query = em.createQuery("select s from School s where s.name = ?1");
query.setParameter(1, name);
query.setMaxResults(1);
return (School) query.getSingleResult();
}
}
@Component
@Transactional
public class CourseDao implements IBaseDao<Course> { @PersistenceContext
private EntityManager em;
@Override
public int save(Course o) {
// TODO Auto-generated method stub
if (0 == o.getId()) {
em.persist(o);
} else {
em.merge(o);
}
return o.getId();
} @Override
public Course find(int id) {
// TODO Auto-generated method stub
return em.find(Course.class, id);
} @Override
public void remove(int id) {
// TODO Auto-generated method stub
Course cos = find(id);
if (null != cos) {
em.remove(cos);
}
}
public Course findByName(String name) {
Query query = em.createQuery("select c from Course c where c.name = ?1");
query.setParameter(1, name);
query.setMaxResults(1);
return (Course) query.getSingleResult();
}
}
@Entity
@Table(name="course")
public class Course implements Serializable {
private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int id; @Column(nullable=false, length=20)
private String name; //bi-directional many-to-one association to StudentCourse
@OneToMany(mappedBy="course", cascade = ALL, fetch = FetchType.EAGER)
private List<StudentCourse> studentCourses; public Course() {
} public int getId() {
return this.id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return this.name;
} public void setName(String name) {
this.name = name;
} public List<StudentCourse> getStudentCourses() {
return this.studentCourses;
} public void setStudentCourses(List<StudentCourse> studentCourses) {
this.studentCourses = studentCourses;
}
public void addStudentCourse(StudentCourse stuCos) {
if (null == this.studentCourses) {
this.studentCourses = new ArrayList<StudentCourse>();
}
this.studentCourses.add(stuCos);
}
}@Entity
@Table(name="school")
public class School implements Serializable {
private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int id; @Column(nullable=false, length=10)
private String name; //bi-directional many-to-one association to Student
@OneToMany(mappedBy="school", cascade = ALL, fetch = FetchType.EAGER)
private List<Student> students; public School() {
} public int getId() {
return this.id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return this.name;
} public void setName(String name) {
this.name = name;
} public List<Student> getStudents() {
return this.students;
} public void setStudents(List<Student> students) {
this.students = students;
}
public void addStudent(Student stu) {
if (null == this.students) {
this.students = new ArrayList<Student>();
}
this.students.add(stu);
}
}TestDao中testSchCRUD(),当给课程及学生建立联系后,通过find找不到相应的数据;如果关系的建立是通过One端类Student进行,那么find也可以找到;如果将tomcat重启,find也可以找到数据。已经被这个问题困扰很久了,急求各位找出原因。多谢!!openjpatransactionalspringmysql
解决方案 »
- Java读取文件夹下的所有txt文件并显示在web页面中……有点晕
- 求教tapestry5如何下载文件
- hibernate的NamingStrategy能在配置文件中配置么
- C# 转为 java 代码
- 请问Struts2中如何让<s:tree>的初始状态是全部展开的样子?谢谢!
- 面对众多的报表工具,我们该如何选择,欢迎大家发言。。。。
- 怎样用Java实现注册一个用户,就给一个目录链接,如http://www.msn.com/space/myname
- 伤透脑筋!jdom的配置问题!
- 关于持久性对象的问题:
- 我很疑惑,关于EJB.
- 项目从tomcat上移植到weblogic上一直报错
- 用ssh做存储过程调用事务的控制
所有Dao类定义的开头,都有@Transactional标记,应该内部所有函数都是在一个事务内的吧?顺便问一下,CascadeType.DETACH 是什么作用?当在StudentCourse中增加这个级联时,find就可以取到数据了。@Entity
@Table(name="student_course")
public class StudentCourse implements Serializable {
private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int id; //bi-directional many-to-one association to Course
@ManyToOne(cascade = {REFRESH, MERGE, PERSIST})
@JoinColumn(name="cos_id", nullable=false)
private Course course; //bi-directional many-to-one association to Student
@ManyToOne(cascade = {REFRESH, MERGE, PERSIST, DETACH})
@JoinColumn(name="stu_id", nullable=false)
private Student student; public StudentCourse() {
} public int getId() {
return this.id;
} public void setId(int id) {
this.id = id;
} public Course getCourse() {
return this.course;
} public void setCourse(Course course) {
this.course = course;
} public Student getStudent() {
return this.student;
} public void setStudent(Student student) {
this.student = student;
} @Override
public boolean equals(Object obj) {
if (!(obj instanceof StudentCourse)) {
return false;
}
if (obj == this) {
return true;
}
StudentCourse stuCos = (StudentCourse) obj;
if (stuCos.getCourse().getId() == this.getCourse().getId()
&& stuCos.getStudent().getId() == this.getStudent().getId()) {
return true;
}
return super.equals(obj);
}
}@Entity
@Table(name="student")
public class Student implements Serializable {
private static final long serialVersionUID = 1L; @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int id; @Column(nullable=false, length=10)
private String name; //bi-directional many-to-one association to School
@ManyToOne
@JoinColumn(name="school_id")
private School school; //bi-directional many-to-one association to StudentCourse
@OneToMany(mappedBy="student", cascade = ALL, fetch = FetchType.EAGER)
private Set<StudentCourse> studentCourses; public Student() {
} public int getId() {
return this.id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return this.name;
} public void setName(String name) {
this.name = name;
} public School getSchool() {
return this.school;
} public void setSchool(School school) {
this.school = school;
} public Set<StudentCourse> getStudentCourses() {
return this.studentCourses;
} public void setStudentCourses(Set<StudentCourse> studentCourses) {
this.studentCourses = studentCourses;
}
public void addStudentCourse(StudentCourse stuCos) {
if (null == this.studentCourses) {
this.studentCourses = new HashSet<StudentCourse>();
}
this.studentCourses.add(stuCos);
}
}
试一下 o = em.merge(o);
关于 persist, merge
看看这几个链接
http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge
http://stackoverflow.com/questions/4509086/what-is-the-difference-between-persist-and-merge-in-hibernate
http://spitballer.blogspot.de/2010/04/jpa-persisting-vs-merging-entites.html