JPA EntityExistsException

15,946

Solution 1

Either you are directly calling persist on your Genre instances, or you are calling persist on movie and the movie->Genre mapping has cascade persist. JPA requires providers to throw an exception when persist is called on a detached entity, since persist means you want the provider to insert it, and it is detached because it already exists. So you will get an exception. Sounds like your parser is not able to tell that the Genre entities are the same instance, and so is creating multiple instances of the same data. If this cannot be fixed, you might try using merge instead. Merge will check first if the entity instance is new or detached. If it is new, it will insert, while if it is detached, it will retrieve the data and update it in the database.

Other options would be to make sure you are not calling persist on detached Genre instances. Remove the cascade persist settings on relationships, and ensure that you manually call persist or merge on new Genre instances rather than rely on cascade persist settings.

Solution 2

You just cannot insert two elements with the same identifier. That id must be unique, if not, the database cannot identify the object (oh the irony), and that's why it gives you the exception.

Create a new field called movieId (or whatever you want to name it) and store the id from the xml in that field, but not in the database identifier "id".

Solution 3

You just cannot insert two objects with the same identifier(id). It throws EntityExistsException,

if the entity already exists. (If the entity already exists, the EntityExistsException may be thrown when the persist operation is invoked, or the EntityExistsException or another PersistenceException may be thrown at flush or commit time.)

Solution

You can create a new field for movieId, which will store the id of the movie from the XML. but this will create unnecessary redundancy of the data. For the Genre, you should create a new table where you will define movie_genre mapping. You can use one to many mapping for this purpose.

Share:
15,946
user1882812
Author by

user1882812

Updated on July 14, 2022

Comments

  • user1882812
    user1882812 almost 2 years

    The problem that I'm currently facing is the following:

    Exception in thread "main" javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [de.entities.Genre#28]
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1359)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1316)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:881)
    at de.model.DatabaseBuilder.importData(DatabaseBuilder.java:87)
    at de.main.Main.main(Main.java:55)
    

    So the Exception tells me that I want to insert two different objects with the same primary key id.

    All my datas I want to insert into a database using JPA are coming from an XML file. I parse this file with a SAXParser. Of course there are many genre entries with the id 28 because many movies have the same genre.

    If I use auto-generated ids, the data wont be correct anymore because all id's are correctly given by the XML file.

    How can I solve this problem? Why isn't JPA not just ignoring the fact, that this object is already present in the database and just inserting the ids of the movies and the genres in my m:n table?

  • user1882812
    user1882812 almost 11 years
    But with that i will have many multiply entries in my datastore. If Movie A has Thriller and Action as Genre and Movie C also has Thriller and Action as Genre, i will have Thriller, Action, Thriller, Action in my Genres Table. Thats not cool ^^
  • aran
    aran almost 11 years
    I don't think you're getting the idea. You can save the ID from the XML. For example, you store Movie A. Movie A will get the DB unique ID 1 (this is not relevant and you just ignore it, that's the way it works in DB), then you make a new FIELD (not a table) called movieId, and you store there the value 28 of your example. I don't see any problem with tables being not cool? This is basic DB how-to.
  • user1882812
    user1882812 almost 11 years
    This i understood well and it solves the problem i described above but it will create another problem -> redundant! With your example: Movie A has no a GenreID entry 28 In my Genre Table i also have a GenreID 28 for example for the Genre Action. Now another Movie has the Genre Action. Again in in both tables the GenreID 28 is inserted but with the autogenerated ID's im using as primary key the 28 doesnt matter, so he will insert the Action Genre twice!!!!!!!
  • user1882812
    user1882812 almost 11 years
    I just dont get it :( Isnt there the possibility to just return the id of a row already inserted in the table and to take this id to insert a new data in my m:n table? Genre 28 is in table, another movie with genre 28 is inserted. instead of inserting this genre again, just take the id of the first genre 28 and put it into the m:n table of MovieGenre... why isnt that possible?
  • user1882812
    user1882812 almost 11 years
    Using CascadeType.MERGE also leads to the same error: Exception in thread "main" javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [de.entities.Genre#28]
  • Chris
    Chris almost 11 years
    It is. But you don't call persist on Genre to do it. Nor do you mark the relationship as cascade persist. The relation is tied to the owning entity and will use the genre Id values regardless of cascade settings. Put another way, the cascade settings apply to genre, not the relationship.
  • yashjain12yj
    yashjain12yj over 4 years
    For this, you have to make another entity or enum for Genre, and give the id of the Genre from table to movies.
  • RoutesMaps.com
    RoutesMaps.com over 2 years
    Thank you @Chris!