Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Change tracking of many-to-many relationship broken?
Change tracking of many-to-many relationship broken? [message #378580] Mon, 04 August 2008 16:11 Go to next message
Frank Schwarz is currently offline Frank SchwarzFriend
Messages: 25
Registered: July 2009
Location: Dresden
Junior Member
Consider this code snippet: (Person <-> Address is a many-to-many
relationship)

@SuppressWarnings("unchecked")
private static void update(EntityManagerFactory entityManagerFactory) {
EntityManager entityManager = entityManagerFactory
.createEntityManager();
try {
entityManager.getTransaction().begin();
Query query = entityManager.createQuery("SELECT p FROM Person p");
Collection<Person> collection = (Collection<Person>) query
.getResultList();
Address address = new Address();
address.setStreet("Oak Lane 12");
address.setCity("Dallas");
for (Person person : collection) {
person.getAddresses().add(address);
address.getPersons().add(person);
}
entityManager.getTransaction().commit();
} finally {
if (entityManager.getTransaction().isActive()) {
entityManager.getTransaction().rollback();
}
entityManager.close();
}
}

The database has already two person-entities beforehand. The execution of
this piece of code does not alter the database - it should, however,
insert an Address entity with corresponding entries in the join table
PERSON_ADDRESS. However, a subsequent query for person-entities reveals an
additional Address-object associated with each person, that only consists
of uninitialized properties.

Is this a known bug?

Kind regards,
Frank
Re: Change tracking of many-to-many relationship broken? [message #378582 is a reply to message #378580] Tue, 05 August 2008 05:28 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> Consider this code snippet: (Person <-> Address is a many-to-many
> relationship)

Maybe you should also include the relevant portions of the entities, the error could be in the mapping?

Tom
Re: Change tracking of many-to-many relationship broken? [message #378584 is a reply to message #378582] Tue, 05 August 2008 06:20 Go to previous messageGo to next message
Frank Schwarz is currently offline Frank SchwarzFriend
Messages: 25
Registered: July 2009
Location: Dresden
Junior Member
The mapping is straightforward and has proven to work with other O/R
mappers:

@Entity
public class Address {

public Address() {
}

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
private String street;
private String city;

@ManyToMany(cascade = CascadeType.ALL)
private Set<Person> persons = new HashSet<Person>();
//...
}

public class Person {

public Person() {
}

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
private String firstName;
private String lastName;

@ManyToMany(mappedBy = "persons", cascade = CascadeType.ALL)
private Set<Address> addresses = new HashSet<Address>();
//...
}
Re: Change tracking of many-to-many relationship broken? [message #378586 is a reply to message #378584] Tue, 05 August 2008 07:44 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
To me this looks ok indeed, so I'll leave it to the EclipseLink developers to comment on.
Re: Change tracking of many-to-many relationship broken? [message #378588 is a reply to message #378580] Tue, 05 August 2008 09:36 Go to previous messageGo to next message
Frank Schwarz is currently offline Frank SchwarzFriend
Messages: 25
Registered: July 2009
Location: Dresden
Junior Member
It seems to be a lazy initialization problem (or a configuration problem
on my side):

@SuppressWarnings("unchecked")
private static void update(EntityManagerFactory entityManagerFactory) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
try {
entityManager.getTransaction().begin();
Query query = entityManager.createQuery("SELECT p FROM Person p");
Collection<Person> collection = (Collection<Person>) query.getResultList();
Address address = new Address();
address.setStreet("Oak Lane 12");
address.setCity("Dallas");
for (Person person : collection) {
// provoke initialization
person.getAddresses().size();
person.getAddresses().add(address);
address.getPersons().add(person);
}
entityManager.getTransaction().commit();
} finally {
if (entityManager.getTransaction().isActive()) {
entityManager.getTransaction().rollback();
}
entityManager.close();
}
}


With the addition of "person.getAddresses().size();" in the for-loop
everything is fine.

Any comments?

-- Frank
Re: Change tracking of many-to-many relationship broken? [message #378589 is a reply to message #378588] Tue, 05 August 2008 12:35 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 807
Registered: July 2009
Senior Member
> With the addition of "person.getAddresses().size();" in the for-loop
> everything is fine.


Only that I have experienced similar situations, which I usually solve by creating a new collection immediately on the query.

Collection<Person> collection = new ArrayList<Person>( query.getResultList() );

I'm not sure if this behavior is faulty as per the JPA definition, because this would be one of the first unittests, I'd gather. But it is unexpected behavior and often causes unnecessary debug work. The JPA1.0 has issues in the "unexpected behavior" area. :-)
Re: Change tracking of many-to-many relationship broken? [message #378597 is a reply to message #378588] Tue, 05 August 2008 13:51 Go to previous messageGo to next message
James is currently offline JamesFriend
Messages: 272
Registered: July 2009
Senior Member
This is very odd, it seems to be an issue with attribute change tracking,
and a read-only many-to-many mapping. I think this is causing the address
to not be persisted. If you call persist on the Address, does it commit
correctly?

If so, it would seem to be a bug, please log a bug for the issue, include
the example code and a log trace on finest.

https://bugs.eclipse.org/bugs/

The workaround for now is either your size call, calling persist on the
Address, or using the @ChangeTracking annotation to use deferred change
tracking for Person class.

-- James
Re: Change tracking of many-to-many relationship broken? [message #378600 is a reply to message #378597] Tue, 05 August 2008 15:25 Go to previous message
Frank Schwarz is currently offline Frank SchwarzFriend
Messages: 25
Registered: July 2009
Location: Dresden
Junior Member
Bug report filed as https://bugs.eclipse.org/bugs/show_bug.cgi?id=243176

-- Frank
Previous Topic:left side of the IN operator missing?
Next Topic:many table, one entity, annotation driven?
Goto Forum:
  


Current Time: Fri Nov 28 04:48:02 GMT 2014

Powered by FUDForum. Page generated in 0.02031 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software