openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeremy Bauer <techhu...@gmail.com>
Subject Re: OpenJPA-2.0.0-snapshot Question with @ManyToMany
Date Mon, 01 Jun 2009 16:49:23 GMT
Hi,

Interesting that this works on Hibernate.  The first potential issue I found
in the test is that it uses a hardcoded id and your entities are annotated
with @GeneratedValue.  Depending on how the value is generated, the values
could be different between test runs and providers.  Storing away the id of
the persisted entities (in static fields, for example) is a safer and more
consistent way to make sure the test accesses the same entities in future
test variations.

The NPE is the result of the student.teachers collection being null.  While
the class contains code to set it to new HashSet upon construction, OpenJPA
sets it to null after the find operation - since the set did not contain any
elements when Student was persisted.  Modifying the addTeacher method as
below corrected the NPE and the test passed.

       public void addTeacher(Teacher teacher) {
           if (teachers == null)
               teachers = new HashSet<Teacher>();
           this.teachers.add(teacher);
       }

Based on the behavior I've seen, I do not think this is a bug in OpenJPA.
While I haven't tested with Hibernate, I suspect it is just a difference in
how empty/null collections are stored and initialized by each provider.

hth,
-Jeremy

On Mon, Jun 1, 2009 at 9:03 AM, opengloves <opengloves@gmail.com> wrote:

>
> IDE Environment: Eclipse-3.4
> DB Environment: Apache-Derby-10.5.1.1
> JDK Environment: Sun JDK-1.6.0_07
> Jar Environment: from
>
> http://openjpa.apache.org/builds/latest/downloads/apache-openjpa-2.0.0-SNAPSHOT-binary.zip
> Eclipse PlugIn Environment:Apache-Derby, JUnit4
>
> I want to test the @ManyToMany(the example is Teacher and Student, many to
> many)
>
> The code is this:
> Student.java
> @Entity
> public class Student {
>        private int id;
>        private String name;
>        private Set<Teacher> teachers = new HashSet<Teacher>();
>        @Id
>        @GeneratedValue
>        public int getId() {
>                return id;
>        }
>        public void setId(int id) {
>                this.id = id;
>        }
>        @Column(length = 10, nullable = false)
>        public String getName() {
>                return name;
>        }
>        public void setName(String name) {
>                this.name = name;
>        }
>        @ManyToMany(cascade = { CascadeType.REFRESH })
>        @JoinTable(
>                name = "STUDENT_TEACHER",
>                inverseJoinColumns = @JoinColumn(name = "TEACHER_ID"),
>                joinColumns = @JoinColumn(name = "STUDENT_ID")
>        )
>        public Set<Teacher> getTeachers() {
>                return teachers;
>        }
>        public void setTeachers(Set<Teacher> teachers) {
>                this.teachers = teachers;
>        }
>        public void addTeacher(Teacher teacher) {
>                this.teachers.add(teacher);
>        }
>        public void removeTeacher(Teacher teacher) {
>                if (this.teachers.contains(teacher)) {
>                        this.teachers.remove(teacher);
>                }
>        }
> }
> Teacher.java
> @Entity
> public class Teacher {
>        private int id;
>        private String name;
>        private Set<Student> students = new HashSet<Student>();
>        @Id
>        @GeneratedValue
>        public int getId() {
>                return id;
>        }
>        public void setId(int id) {
>                this.id = id;
>        }
>        @Column(length=10, nullable=false)
>        public String getName() {
>                return name;
>        }
>        public void setName(String name) {
>                this.name = name;
>        }
>        @ManyToMany(cascade={CascadeType.REFRESH}, mappedBy="teachers" )
>        public Set<Student> getStudents() {
>                return students;
>        }
>        public void setStudents(Set<Student> students) {
>                this.students = students;
>        }
>        @Override
>        public int hashCode() {
>                final int prime = 31;
>                int result = 1;
>                result = prime * result + id;
>                return result;
>        }
>        @Override
>        public boolean equals(Object obj) {
>                if (this == obj)
>                        return true;
>                if (obj == null)
>                        return false;
>                if (getClass() != obj.getClass())
>                        return false;
>                Teacher other = (Teacher) obj;
>                if (id != other.id)
>                        return false;
>                return true;
>        }
> }
> ManyToManyTest.java
> public class ManyToManyTest {
>        @Test
>        public void testPersist(){
>                EntityManagerFactory emf =
> Persistence.createEntityManagerFactory("sample");
>                EntityManager em = emf.createEntityManager();
>                EntityTransaction et = em.getTransaction();
>                et.begin();
>                Student student = new Student();
>                student.setName("student1");
>                Teacher teacher = new Teacher();
>                teacher.setName("teacher1");
>                em.persist(student);
>                em.persist(teacher);
>                et.commit();
>                em.close();
>                emf.close();
>        }
>        @Test
>        public void testPersistJoinTable(){
>                EntityManagerFactory emf =
> Persistence.createEntityManagerFactory("sample");
>                EntityManager em = emf.createEntityManager();
>                EntityTransaction et = em.getTransaction();
>                et.begin();
>                Student student = em.find(Student.class, 1);
>                Teacher teacher = em.getReference(Teacher.class, 51);
>                student.addTeacher(teacher);
>                et.commit();
>                em.close();
>                emf.close();
>        }
> }
> and META-INF/persistence.xml is
> <persistence-unit name="sample" transaction-type="RESOURCE_LOCAL">
>
> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
>                <!-- Many to many Type -->
>                <class>org.sample.demo.jpa.entity.manytomany.Student</class>
>                <class>org.sample.demo.jpa.entity.manytomany.Teacher</class>
>                <properties>
>                        <property name="openjpa.jdbc.DBDictionary"
> value="derby"/>
>                        <property name="openjpa.ConnectionURL"
> value="jdbc:derby://localhost:1527/sample;create=true" />
>                        <property name="openjpa.ConnectionDriverName"
> value="org.apache.derby.jdbc.ClientDriver" />
>                        <property name="openjpa.ConnectionUserName"
> value="user" />
>                        <property name="openjpa.ConnectionPassword"
> value="secret" />
>                        <property name="openjpa.jdbc.SynchronizeMappings"
> value="buildSchema(ForeignKeys=true)"/>
>                </properties>
>        </persistence-unit>
> ---------------------------------------------------------
> I tested the method testPersist(), everythind is right.
>
> Question is when I tested the method testPersistJoinTable() It throws a
> NullPointException, when it processed in Student student =
> em.find(Student.class, 1);, the student object's Set<Teacher> is null, and
> I
> could not insert into  table STUDENT_TEACHER.(The student's id and
> teacher's
> id were exist).
> after  that I use Hibernate, It's right, and I can do addTeacher(Teacher)
> method. and Set<Teacher> is not null.
>
> I think a use JPA and it should be both right……
> Does someone can fix this question? any help is OK.
>
> ---
> Thanks.
> Open Gloves
> --
> View this message in context:
> http://n2.nabble.com/OpenJPA-2.0.0-snapshot-Question-with-%40ManyToMany-tp3006387p3006387.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message