Open Gloves,

Apologies.  I did not verify that the insert into the collection actually
took place.  After re-running the test, paying close attention to the trace
output, I found the source of the problem.  During entity enhancement
several warnings were logged of this form:

1656  sample  WARN   [main] openjpa.Enhance - Detected the following
possible violations of the restrictions placed on property access persistent
types:
"entities.Student" uses property access, but its field "teachers" is
accessed directly in method "removeTeacher" defined in "entities.Student".

In short, non-persistent methods in Teacher and Student are accessing fields
directly instead of calling the persistent property methods.  In order for
OpenJPA to effectively track changes in the persistent properties they must
be accessed instead of the fields.  Modifying the addTeacher and
removeTeacher methods as below corrected the problem.

       public void addTeacher(Teacher teacher) {
           if (getTeachers() == null)
               setTeachers(new HashSet<Teacher>());
           getTeachers().add(teacher);
       }
       public void removeTeacher(Teacher teacher) {
           if (getTeachers().contains(teacher)) {
               getTeachers().remove(teacher);
           }
       }

This looks to be another implementation difference between OpenJPA and
Hibernate.

-Jeremy


On Tue, Jun 2, 2009 at 12:51 AM, opengloves <openglo...@gmail.com> wrote:

>
> Hi,
> Thanks for your response.
> I hardcoded is just for test @ManyToMany and see the effect.
> @GeneratedValue
> is not the point of this issue.
> I also do not think this is the bug of OpenJPA, and I had been modified the
> code like your advice before, and It didn't passed test either. because the
> test code is passed, but it didn't do the right thing because the data is
> not insert into the table STUDENT_TEACHER, this is strange, and I also test
> the hibernate without if block and it works, and I tested the method
> testPersistJoinTable() twice and the table is also contain one record. and
> this is good, this is the META-INF/persistence.xml about hibernate
> <persistence-unit name="sample" transaction-type="RESOURCE_LOCAL">
>
>  <class>org.sample.demo.jpa.entity.manytomany.Student</class>
>                <class>org.sample.demo.jpa.entity.manytomany.Teacher</class>
>                <properties>
>                         <property name="hibernate.dialect"
> value="org.hibernate.dialect.DerbyDialect"/>
>                        <property name="hibernate.connection.url"
> value="jdbc:derby://localhost:1527/sample;create=true" />
>                         <property name="hibernate.connection.driver_class"
> value="org.apache.derby.jdbc.ClientDriver" />
>                         <property name="hibernate.connection.username"
> value="user" />
>                        <property name="hibernate.connection.password"
> value="secret" />
>                        <property name="hibernate.hbm2ddl.auto"
> value="update"/>
>                </properties>
>        </persistence-unit>
> Jar Environment: antlr-2.7.6, commons-collections-3.1, dom4j-1.6.1,
> ejb3-persistence, hibernate3, hibernate-annotations,
> hibernate-cglib-repack-2.1_3, hibernate-commons-annotations,
> hibernate-entitymanager, javassist-3.4.GA, jta-1.1, log4j-1.2.15,
> slf4j-api-1.5.2, slf4j-log4j12-1.5.0.
> Other environment and codes are the same.(Student.java, Teacher.java,
> ManyToManyTest.java are the same)
>
> After modified the code, I think this is strange: the test is passed and
> the
> data is not insert into the table.
> And I come here, find help. Or maybe this is a bug?
> I think add this if block is the provider dependence, maybe.
>
> ------
> Thanks
> Open Gloves
>
>
> Jeremy Bauer wrote:
> >
> > 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
> >
> >
>
> --
> View this message in context:
> http://n2.nabble.com/OpenJPA-2.0.0-snapshot-Question-with-%40ManyToMany-tp3006387p3010520.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>
>

Reply via email to