Bug 497074 - Cascade.PERSIST on java.util.map<Entity, Entity> fails to persist key entities.
Summary: Cascade.PERSIST on java.util.map<Entity, Entity> fails to persist key entities.
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-06-30 06:57 EDT by Christian Weiers CLA
Modified: 2022-06-09 10:06 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Weiers CLA 2016-06-30 06:57:15 EDT
When using cascade.PERSIST on a java.util.map (as seen below), only the value of the map is persisted to the database.

@Entity
public class MapContainer {
	
	@Id
	@GeneratedValue
	private Long id;
	
	
	@OneToMany(cascade = CascadeType.PERSIST)
	@JoinTable(name = "Map",
	           joinColumns = @JoinColumn
                                (name = "Mapcontainer", referencedColumnName = "ID") , 
				inverseJoinColumns = @JoinColumn(name = "Value_ID", referencedColumnName = "ID") )
	@MapKeyJoinColumn(name = "Key_ID")
	private Map<KeyClass, ValueClass> map;
}

KeyClass and ValueClass are simple entities with only an @Id field and nothing else.



When the key entities have not been persisted beforehand, the following exception is thrown:

[EL Warning]: 2016-06-30 12:11:54.579--UnitOfWork(674882504)--java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: jpa.test.minimalExample.KeyClass@511f5b1d.

Expected behaviour:
If both key and value are entities, entitymanager operations should cascade to both the key entities AND the value entities (as it happens in other jpa implementations). 

As it is now, one has to manually handle persistance of every key object, or have each value hold a reference to its key (At least that is my conclusion for now, but I'd be happy to know I'm wrong and everything works fine if I'd just do it right)

________________________
If needed: persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
  version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="Minimal" transaction-type="RESOURCE_LOCAL">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>	
 	
 	<class>jpa.test.minimalExample.KeyClass</class>
 	<class>jpa.test.minimalExample.ValueClass</class>
 	<class>jpa.test.minimalExample.MapContainer</class>
 	
 <properties>
  <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver" />
  <property name="javax.persistence.jdbc.url"  value="jdbc:derby://localhost:1527/simpleTest/;create=true" />
  <property name="javax.persistence.jdbc.user" value="test" />
  <property name="javax.persistence.jdbc.password" value="test" />

  <!-- EclipseLink should create the database schema automatically -->
  <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
  <property name="eclipselink.ddl-generation.output-mode" value="database" />
 </properties>

  </persistence-unit>
</persistence> 

_____________________________
Main:

public static void main(String[] args) {

		EntityManagerFactory factory = Persistence.createEntityManagerFactory("Minimal");
		EntityManager em = factory.createEntityManager();

		MapContainer container = new MapContainer();
		
                KeyClass key = new KeyClass();
		ValueClass value = new ValueClass();
		
		container.setMap(new HashMap<KeyClass, ValueClass>());
		container.getMap().put(key, value);
		
		em.getTransaction().begin();
		em.persist(container);
		em.getTransaction().commit();
		em.close();

	}
Comment 1 Eclipse Webmaster CLA 2022-06-09 10:06:01 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink