Detached entity passed to persist ошибка

I am trying to run this basic JPA/EJB code:

public static void main(String[] args){
         UserBean user = new UserBean();
         user.setId(1);
         user.setUserName("name1");
         user.setPassword("passwd1");
         em.persist(user);
  }

I get this error:

javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.JPA.Database

Any ideas?

I search on the internet and the reason I found was:

This was caused by how you created the objects, i.e. If you set the ID property explicitly. Removing ID assignment fixed it.

But I didn’t get it, what will I have to modify to get the code working?

Manuel Drieschmanns's user avatar

asked Mar 14, 2010 at 8:25

zengr's user avatar

The error occurs because the object’s ID is set. Hibernate distinguishes between transient and detached objects and persist works only with transient objects. If persist concludes the object is detached (which it will because the ID is set), it will return the «detached object passed to persist» error. You can find more details here and here.

However, this only applies if you have specified the primary key to be auto-generated: if the field is configured to always be set manually, then your code works.

answered Mar 14, 2010 at 11:44

Tomislav Nakic-Alfirevic's user avatar

3

ERD

Let’s say you have two entities Album and Photo. Album contains many photos, so it’s a one to many relationship.

Album class

@Entity
public class Album {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    Integer albumId;

    String albumName;

    @OneToMany(targetEntity=Photo.class,mappedBy="album",cascade={CascadeType.ALL},orphanRemoval=true)
    Set<Photo> photos = new HashSet<Photo>();
}

Photo class

@Entity
public class Photo{
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    Integer photo_id;

    String photoName;

    @ManyToOne(targetEntity=Album.class)
    @JoinColumn(name="album_id")
    Album album;

}

What you have to do before persist or merge is to set the Album reference in each photos.

        Album myAlbum = new Album();
        Photo photo1 = new Photo();
        Photo photo2 = new Photo();

        photo1.setAlbum(myAlbum);
        photo2.setAlbum(myAlbum);       

That is how to attach the related entity before you persist or merge.

answered Feb 5, 2011 at 5:00

zawhtut's user avatar

zawhtutzawhtut

8,3115 gold badges51 silver badges76 bronze badges

2

remove

user.setId(1);

because it is auto generate on the DB,
and continue with persist command.

answered Apr 20, 2011 at 7:27

Ammar Bozorgvar's user avatar

I got the answer, I was using:

em.persist(user);

I used merge in place of persist:

em.merge(user);

But no idea, why persist didn’t work. :(

answered Mar 14, 2010 at 9:07

zengr's user avatar

zengrzengr

38.2k37 gold badges128 silver badges192 bronze badges

3

if you use to generate the id = GenerationType.AUTO strategy in your entity.

Replaces user.setId (1) by user.setId (null), and the problem is solved.

j0k's user avatar

j0k

22.5k28 gold badges79 silver badges89 bronze badges

answered Aug 24, 2012 at 4:49

Sergio Ordóñez's user avatar

Here .persist() only will insert the record.If we use .merge() it will check is there any record exist with the current ID, If it exists, it will update otherwise it will insert a new record.

SkyWalker's user avatar

SkyWalker

28.2k13 gold badges74 silver badges132 bronze badges

answered Jul 16, 2012 at 14:41

PSR's user avatar

PSRPSR

39.6k41 gold badges111 silver badges150 bronze badges

1

I know its kind of too late and proly every one got the answer. But little bit more to add to this: when GenerateType is set, persist() on an object is expected to get an id generated.

If there is a value set to the Id by user already, hibernate treats it as saved record and so it is treated as detached.

if the id is null — in this situation a null pointer exception is raised when the type is AUTO or IDENTITY etc unless the id is generated from a table or a sequece etc.

design: this happens when the table has a bean property as primary key.
GenerateType must be set only when an id is autogenerated.
remove this and the insert should work with the user specified id.
(it is a bad design to have a property mapped to primary key field)

answered Jul 5, 2012 at 21:08

haripriya's user avatar

haripriyaharipriya

511 silver badge1 bronze badge

If you set id in your database to be primary key and autoincrement, then this line of code is wrong:

user.setId(1);

Try with this:

public static void main(String[] args){
         UserBean user = new UserBean();
         user.setUserName("name1");
         user.setPassword("passwd1");
         em.persist(user);
  }

answered Feb 28, 2016 at 11:47

Nemus's user avatar

NemusNemus

3,85912 gold badges38 silver badges56 bronze badges

1

I had this problem and it was caused by the second level cache:

  1. I persisted an entity using hibernate
  2. Then I deleted the row created from a separate process that didn’t interact with the second level cache
  3. I persisted another entity with the same identifier (my identifier values are not auto-generated)

Hence, because the cache wasn’t invalidated, hibernate assumed that it was dealing with a detached instance of the same entity.

answered Mar 11, 2011 at 15:55

hertzsprung's user avatar

hertzsprunghertzsprung

9,3654 gold badges41 silver badges76 bronze badges

Detached entity passed to persist exception or its variations like spring detached entity passed to persist can come up in various situations, among which persisting an entity that is already present in your database ranks at the top.detached entity passed to persist

The term “detached entity” in the exception statement refers to an entity already residing in the database because you have persisted the same earlier. Now, this post will state the different causes of the given exception and help you normalize the problematic situations to make your code work again.

After reading this article, you’ll be aware of the next step that’ll eliminate the same exception permanently.

Contents

  • What Invites the Detached Entity Passed To Persist Exception?
    • – You Are Trying To Persist an Already Persisted Entity
    • – You Are Having a Setter While Persisting an Entity
    • – You Are Setting an ID for an Entity While It’s Auto-generated
    • – Your equals() Method Has a Child Collection
  • How To Save Yourself from the Detached Entity Passed To Persist Exception?
    • – Choose Merge Over Persist or All
    • – Avoid Specifying Cascading With the Child Entity
    • – Remove the Setters
    • – Don’t Set the ID When It’s Not Required
    • – Never Pass a Child Collection To the equals() Method
  • FAQ
    • 1. How Can You Make a Detached Entity Persistent Again?
    • 2. How Would You Differentiate Between Persist and Merge?
    • 3. How Is save() Different from persist() in Hibernate?
    • 4. What Are the Transient and Persistent Objects?
    • 5. Which Methods Should You Call To Make the Objects Persistent?
  • Conclusion

What Invites the Detached Entity Passed To Persist Exception?

Your attempt to persist an already persisted entity can invite the spring data jpa detached entity passed to persist exception to your system. Plus, assigning a value to an auto-generated column, having setters while persisting an entity, or passing a child collection to the equals() function also causes this error.

– You Are Trying To Persist an Already Persisted Entity

Trying to persist an already persisted entity can make the detached entity passed to persist test exception pop up on your screen. The reason is simple. You can not add an already existing entity to the database. However, you can always update it or add more details to it.

For example, you have created the student and teacher entities. The given entities have many-to-one relationships between them. The idea is based on a real-world concept pointing toward a single teacher teaching many students, and every student is taught by one teacher. Next, you have created a teacher object, assigned multiple students to it, and persisted the same object.

Until this step, everything worked fine. Later, you tried to create an object of the student entity, which has a many-to-one relationship with the teacher entity.

But the moment you try to persist the student object, you’ll get the detached entity passed to persist many-to-one exception disallowing the student object to persist. It is because persisting the student object will also persist the already persisted teacher object, which is not acceptable and impossible.

The reference code showing the entities has been attached below.

@Entity

public class Student {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

@ManyToOne(cascade = {CascadeType.ALL})

Private Teacher byTeacher;

….

@Entity

public class Teacher {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

@OneToMany(cascade = {CascadeType.ALL},fetch= FetchType.EAGER, mappedBy = “byTeacher”)

private Set<Student> students;

– You Are Having a Setter While Persisting an Entity

You aren’t allowed to have setters for an entity if you plan to persist the same. If you try to set a value for an entity, such as an id, while persisting it, you’ll receive the invaliddataaccessapiusageexception: detached entity passed to persist exception. In short, you can’t set values and persist an entity simultaneously.Detached Entity Passed To Persist Causes

For example, you have created an id setter for your employee entity. Now, you want to persist the given entity. Here, the setter will come in the way, pose a hurdle in persisting the employee entity, and result in the same exception.

– You Are Setting an ID for an Entity While It’s Auto-generated

Setting an id or primary key manually while you have switched on its auto-generation setting will bring you closer to the detached entity passed to persist entitymanager exception. It is because the columns with auto-generation settings do not require you to pass values to them.

Imagine having an id column for the books entity in the database. You have specified GenerationType.AUTO for the ID column. Now, if you try to set an id while creating a books object. You’ll end up receiving the stated exception.

The code snippet aligning with the above example is attached here.

@Data

@Entity

@Table(name = “Books”)

public class Book {

@Id

@GeneratedValue

private Long id;

private String name;

private String author;

}

Book book1 = new Book(1, “myBook”, “Anonymous”);

testEntityManager.persist(book1);

– Your equals() Method Has a Child Collection

Passing a child collection to the equals() method will make hibernate assume that every element specified for the child collection is a new object that needs to be persisted instead of an updated value for the existing one. This misassumption might result in the same exception.

Think about it this way. You have an organization entity as a parent entity and an employee entity as a child entity. Now, if you try to run the equals() function with the employee collection, you’ll see the given exception on your screen.

The following block of code depicts the same scenario.

@Entity

public class Organization {

private Long id;

private String orgName;

private Set<Employee> employees;

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (!(obj instanceof Organization))

return false;

Organization obj1 = (Organization) obj;

return Objects.equals(this.id, obj1.id)

&& Objects.equals(this.orgName, other.orgName)

&& Objects.equals(this.employees, other.employees);

}

}

How To Save Yourself from the Detached Entity Passed To Persist Exception?

You can save yourself from the detached entity passed to persist exception by merging the entity that is already persisted, not specifying cascading with the child entity, or removing the setters while persisting an entity. Also, passing null to the auto-generated column can fix the issue.

– Choose Merge Over Persist or All

If the cause of the issue is persisting an already persisted entity, use CascadeType.MERGE instead of CascadeType.PERSIST or CascadeType.ALL with @ManyToOne to make things work for you. It means you should merge the persisted entity instead of persisting it again.

Talking about the example entities discussed above, you should replace CascadeType.ALL following @ManyToOne in the student entity with CascadeType.MERGE. It will ensure that the teacher entity is merged when persisting a student object. Consequently, the given exception will leave your screen too. Here is how the altered student entity should look.

@Entity

public class Student {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

@ManyToOne(cascade = {CascadeType.MERGE})

Private Teacher byTeacher;

– Avoid Specifying Cascading With the Child Entity

If you don’t want to use merge cascading with your child entity, then you might like to skip the cascading type. It will ensure that no action in the database affects the parent entity, which is mostly persisted already. Eventually, you’ll never receive the above exception on your screen.

So, you can alter the student entity as shown below.

@Entity

public class Student {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

@ManyToOne

Private Teacher byTeacher;

– Remove the Setters

It would be best to remove any related setters while persisting an entity to get rid of the detached entity passed to persist panache exception. This way, the setters won’t interrupt the process, and your desired operation will be carried out perfectly. For the previous example, you can remove the id setter to settle things.Detached Entity Passed To Persist Causes Fixes

Deleting the setters is one of the simplest solutions, which will work like magic to eliminate the exception.

– Don’t Set the ID When It’s Not Required

If your id or primary key column is auto-generated, you should not pass an id while creating an object. You can specify null instead of an actual id to let the auto-generated value fit in and remove the said exception from your system.

Considering the Book entity example again, it would be best to create the object like Book book1 = new Book(null, “myBook”, “Anonymous”). Eventually, null will be replaced with an auto-generated id, and the book1 object will be created successfully with a valid id.

– Never Pass a Child Collection To the equals() Method

You should never pass a child collection to the equals() method to avoid hibernate make any misassumptions regarding the given collection. Once everything is clear to hibernate, the exception will disappear from your system. However, please remember that this solution is applied only in relevant cases.

Joining the thread with the previous example, you should remove the coding statement that calls the equals() function with the employee collection. It will help remove the said exception.

FAQ

1. How Can You Make a Detached Entity Persistent Again?

You can make a detached entity persistent again by using the update method of the session. The update method will force an update operation to be executed for the passed object. As the object is originally detached, Hibernate adds this object to the persistence context to make it persistent.

2. How Would You Differentiate Between Persist and Merge?

The difference between persist and merge is that persist should be called only on new entities, while the merge is used to reattach the detached entities. Contrary to the above situations, using merge instead of persist will cause a redundant SQL statement while using the assigned generator.

3. How Is save() Different from persist() in Hibernate?

The save() method is different from the persist() method in hibernate in a way that the save() method lets you assign the identifier value immediately. However, the persist() method fails to confirm the assignment of an identifier value to its persistent state instantly.

4. What Are the Transient and Persistent Objects?

The transient objects are the ones that haven’t been saved yet. It means all of the newly created entities are transient until you persist them. On the other hand, the persistent objects are the ones that have been saved to the database. Entities received from the repository are persistent objects.

5. Which Methods Should You Call To Make the Objects Persistent?

There are a variety of methods you can call to send the objects to the persistent state. The common methods include session.save(e), session.update(e), session.persist(e), session.lock(e), session.saveOrUpdate(e), and session.merge(e). You can execute the one that fits to your need.

Conclusion

The PersistentObjectException: detached entity passed to persist can result from persisting an already persistent entity or setting values for its auto-generated columns. In rare cases, the equals() function with a child collection as an argument can be problematic and result in the said exception. Here you go with a list of solutions extracted from the above post that’ll help you fix the given exception instantly.

  • Merge the persisted entity instead of persisting it again to resolve the exception.
  • Don’t specify any cascading type with the child entity to stay away from the exception.
  • Never provide a value for a column that’ll have its values auto-generated to avoid confusion and, eventually, the exception.
  • Ensure to have zero setters while persisting an entity to avoid the said exception.
  • Don’t pass a child collection to the equals() function to push away the same exception.

Lastly, remember that the more you know about the dos and don’ts of working with the entities and persisting them, the fewer times you’ll encounter the given exception.

  • Author
  • Recent Posts

Position is Everything

Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team

Position is Everything

Ошибка:

org.hibernate.PersistentObjectException: detached entity passed to persist

Пример, когда может возникать этот эксепшн:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

   @Id

    @Column(name = «id»)

    @GeneratedValue(strategy = GenerationType.IDENTITY) // commented for manually set the id

    private long id;

    @Column(name = «login», unique = true, updatable = false)

    private String name;

    //Important to Hibernate!

    @SuppressWarnings(«MySQLConfig»)

    public UsersDataSet() {

    }

    @SuppressWarnings(«MySQLConfig»)

    public UsersDataSet(long id, String name) {

        this.setId(id);

        this.setName(name);

    }

    public UsersDataSet(String name) {

        this.setId(1);

        this.setName(name);

    }

Если не убрать строчку выбора стратегии создания id в автоматическом режиме, то возникнет вышеописанное исключение.

    @GeneratedValue(strategy = GenerationType.IDENTITY)

Причина заключается в том, что запись выше указывает JPA стратегию автоматического создания идентификатора при сохранении (создании) сущности. Однаков в конструкторе уже прописано, что нужно вставить идентификатор вручную. В результате, т.к. индентификатор назначается вручную в конструкторе и отсутствует, то JPA думает, что сохраняется объект, отсутствующий в контексте персистентности (detached from persistence context).

Для исправления либо убирайте в констркуторе указание id, либо убирайте GeneratedValue(strategy = …)

public UsersDataSet(long id, String name) {

       // this.setId(id);

        this.setName(name);

    }

Share Button

11

18350 Total Views 9 Views Today


Views:
16 229

Hello,

if i use the Repository directly to update an Entity it’s works. But if the Repository a Depency inside a Controller i always get the following Error:
Unexpected error occurred: org.hibernate.PersistentObjectException: detached entity passed to persist: example.domain.Pet

I extend the given Example (example-jpa) with the PetRepository. I create a update method inside the Controller:

@Put("/{petId}")`
    HttpStatus update(@QueryValue("petId") Long petId, Pet pet) {
        Optional<Pet> result = petRepository.findById(petId);
        if (result.isPresent()) {
            Pet current = result.get();
            current.setName(pet.getName());
            petRepository.persist(current);

            return HttpStatus.CREATED;
        }

        return HttpStatus.NOT_FOUND;
    }

I added the method as described in the documentation:
Pet persist(Pet entity);

And create a Test for the PUT endpoint:

@MicronautTest
public class PetUpdateControllerTest {

    @Inject
    @Client("/")
    RxHttpClient client;

    @Test
    void test() {
        Pet result = client.toBlocking().retrieve(HttpRequest.GET("/pets/Dino"), Pet.class);

        assertNotNull(result);
        assertEquals("Dino", result.getName());

        result.setName("Heino");
        String url = "/pets/" + result.getId();
        HttpStatus status = client.toBlocking().retrieve(HttpRequest.PUT(url, result), HttpStatus.class);
        assertEquals(204, status.getCode());
    }
}

Then i got this Error:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: example.domain.Pet
	at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
	at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
	at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
	at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:810)
	at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:788)

I discover the same error in my own project.
A direct Test with the Repository works.

Regards
Jan

Every framework has a set of exceptions that indicate common error scenarios. Understanding them will help you turn a task that could drag along for days into a quickly-implemented feature. When working with Hibernate, they tell you about issues with your database queries, mapping mistakes, and problems during write operations.

In this article, I want to show you the most common exceptions and explain how you can avoid or fix them.

Contents

  • 1 Query-Related Exceptions
    • 1.1 NonUniqueResultException
    • 1.2 QuerySyntaxException
    • 1.3 SQLGrammarException
    • 1.4 LazyInitializationException
    • 1.5 MultipleBagFetchException
  • 2 Mapping-Related Exceptions
    • 2.1 MappingException: The Increment Size of the [author_seqence] Sequence Is Set to [50] in the Entity Mapping While the Associated Database Sequence Increment Size Is [1]
  • 3 Update-Related Exceptions
    • 3.1 OptimisticLockException
    • 3.2 PersistentObjectException: Detached Entity Passed to Persist
  • 4 Conclusion

These are the most common Hibernate exceptions. Sometimes, they are caused by a simple typo in your statement or because you called the wrong Query interface method. However, they can also indicate potential performance issues or data inconsistencies.

NonUniqueResultException

All JPA implementations throw the NonUniqueResultException if you call the getSingleResult method on a Query interface and the executed query returns more than one record.

javax.persistence.NonUniqueResultException: query did not return a unique result: 2
	at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:128)
	at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1588)
	...

The NonUniqueResultException most often occurs because:

  • You intentionally wrote a query that returns multiple records and tried executing it by calling the getSingleResult() instead of the getResultList() method. To be honest, that happens to me quite regularly. Luckily, it’s very quick and easy to fix by calling the getResultList() method.
  • You wanted to create a query that returns only one record, but the WHERE clause isn’t as restrictive as you thought. In that case, please check my Guide to JPQL. It tells you everything you need to know to improve your query.
  • You wrote a query that was supposed to return only one record and you stumbled upon inconsistent data. If that happens, then it’s hopefully just some artificially created test data. But, in any case, you should double-check your business logic and add a unique constraint to your table model.

QuerySyntaxException

If Hibernate throws a QuerySyntaxException, you have made a mistake in your JPQL query. In most cases, the mistake will be a simple typo in one of JPQL’s reserved keywords.

Book book = entityManager
					.createQuery("SELECT b FROM Book b LFET JOIN b.author a WHERE a.id=:id", Book.class)
					.setParameter("id", id)
					.getSingleResult();

As you can see in the following log message, Hibernate tells you which part of the query it didn’t understand. In this example, I misspelled the word LEFT in my LEFT JOIN clause.

java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: 
unexpected token: LFET near line 1, column 49 
[SELECT b FROM com.thorben.janssen.entity.Book b LFET JOIN b.author a WHERE a.id=:id]

SQLGrammarException

An SqlGrammarException is very similar to a QuerySyntaxException. It indicates a mistake in a native SQL statement.

Book book = (Book) entityManager
					.createNativeQuery("SELECT b FROM Book b LFET JOIN Author a on b.author_id = a.id WHERE a.id=:id", Book.class)
					.setParameter("id", id)
					.getSingleResult();

Unfortunately, Hibernate’s exception doesn’t provide a lot of information about the actual error. It only tells you that it was unable to extract the ResultSet. But, if you take a look at the end of the stack trace, you should find the exception thrown by your JDBC driver. It usually tells you why the query failed.

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
	... 
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
	... 
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "LFET"
  Position: 22

LazyInitializationException

The LazyInitializationException might not look like a query-related exception because it happens much later. Hibernate throws it if you try to initialize a lazily fetched association without an active Hibernate Session. This usually happens in your UI layer after your backend committed the transaction and closed the Session. Even though it might not look like it, it’s caused by a query that didn’t fetch the required association.

As you can see in the message below, Hibernate tells you which association it wasn’t able to initialize.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: 
com.thorben.janssen.entity.Author.books, could not initialize proxy - no Session

You can fix this exception in multiple ways. The easiest and most commonly used solution is a JOIN FETCH clause. You can use it in your JPQL query to tell Hibernate to initialize the referenced association.

		List<Author> authors = entityManager.createQuery("SELECT a FROM Author a JOIN FETCH a.books", Author.class).getResultList();

MultipleBagFetchException

If you model your to-many associations as java.util.Lists and try to initialize a number of them using a JOIN FETCH clause, Hibernate will throw a MultipleBagFetchException.

List<Book> books = entityManager.createQuery("""
	SELECT b 
	FROM Book b 
		JOIN FETCH b.authors a 
		JOIN FETCH b.reviews r""", 
	Book.class).getResultList();

As I explained in more detail in a previous article, you can fix this exception in two ways:

1. You can change the attribute type to a java.util.Set.

@Entity
public class Book {
	
	@ManyToMany
	private Set<Author> authors = new HashSet<Author>();
	
	@OneToMany(mappedBy = "book")
	private Set<Review> reviews = new HashSet<Review>();
	
	...
}

2. You can use multiple queries that use only one JOIN FETCH clause each. This approach works because Hibernate ensures that a Session contains only one entity object for each database record. If you select the same one with different fetching behavior, Hibernate will merge them in memory.

TypedQuery<Book> q = em.createQuery("""
		SELECT DISTINCT b
		FROM Book b 
			JOIN FETCH b.authors a
		WHERE b.id = 1""",
		Book.class);
q.setHint(QueryHints.PASS_DISTINCT_THROUGH, false);
List<Book> books = q.getResultList();

q = em.createQuery("""
		SELECT DISTINCT b
		FROM Book b 
			JOIN FETCH b.reviews r
		WHERE b.id = 1""",
		Book.class);
q.setHint(QueryHints.PASS_DISTINCT_THROUGH, false);
books = q.getResultList();

I will keep this section short because mapping-related exceptions are rare. That’s mostly because mapping is defined once and used during the entire project.

MappingException: The Increment Size of the [author_seqence] Sequence Is Set to [50] in the Entity Mapping While the Associated Database Sequence Increment Size Is [1]

If you use a database sequence to generate your primary key values and define a @SequenceGenerator, you might get the following exception:

MappingException: The increment size of the [author_seqence] sequence 
is set to [50] in the entity mapping while the associated database sequence 
increment size is [1].

Hibernate throws this exception because it provides an optimization based on the default allocationSize of the @SequenceGenerator. Based on that default setting, the database sequence should get incremented by 50 every time you request a new value. Hibernate then uses the value from the sequence and increments it 49 times internally before requesting another value. This drastically reduces the number of executed JDBC statements.

During the deployment of your persistence layer, Hibernate checks if the referenced database sequence gets incremented by the defined allocationSize. If that’s not the case, it throws a MappingException.

I recommend fixing this exception by increasing the step size on your database sequence. It enables you to use Hibernate’s optimization to improve the performance of your insert operations. If you cannot change the database sequence, you need to set the allocationSize of the @SequenceGenerator to one.

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "author_seq")
@SequenceGenerator(name = "author_seq", allocationSize = 1)
private Long id;

Hibernate throws this kind of exception to inform you about problems during write operations. The two most common ones are the OptimisticLockException and the PersistentObjectException. While the first one is expected to occur at runtime, the second one is always an implementation error.

OptimisticLockException

JPA and Hibernate provide two build-in mechanisms to manage concurrent updates. One of them is called optimistic locking. It causes an OptimisticLockException whenever two or more transactions try to update the same database record at the same time. That lets all except the first transaction fail and prevents the concurrent modification of the record.

javax.persistence.RollbackException: 
Error while committing the transaction
	...
Caused by: javax.persistence.OptimisticLockException: 
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.thorben.janssen.entity.Book#4]
	...
Caused by: org.hibernate.StaleObjectStateException: 
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.thorben.janssen.entity.Book#4]
	...

Optimistic and pessimistic locking are easy and complex at the same time, but that’s a whole other topic. If you want to learn more about it, please join my Hibernate Performance Tuning Online Training.

Technically, there are a few options for fixing an OptimisticLockException. But realistically, all of them require you to merge the operations performed in the parallel transactions. The best and most reliable way to do that is to show an error message to the user when the exception occurs. The user can then find the differences between both changes, resolve errors or inconsistencies, and perform another update.

PersistentObjectException: Detached Entity Passed to Persist

There are two main scenarios in which Hibernate throws this exception.

The first happens when you configure a primary key generation strategy for an entity and set the primary key value programmatically before persisting a new entity. You can easily fix that by removing the code that sets the primary key value. If you’re using field-based access, you should also remove the setter method for the primary key attribute. This prevents you from accidentally setting that attribute in the future.

The second scenario happens when you call the persist method of the EntityManager with a detached entity.

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.thorben.janssen.entity.Author

This is usually the case because you got an entity object from a client application and tried to persist it. In this case, you can fix the exception by calling the merge method on the EntityManager.

Conclusion

If you’re using a framework to implement your application, you should be familiar with its most common exceptions. Hibernate is a complex and powerful framework. So, it’s no surprise that you need to be familiar with a bunch of exceptions.

Most of them are query-related because querying data is highly flexible and the most used part of the framework. The good news is that all of these exceptions include a good description of the error so that you can easily fix it.

  • Destiny 2 ошибка potato
  • Destiny 2 ошибка honeydew
  • Destiny 2 ошибка fig
  • Destiny 2 ошибка coconut
  • Destiny 2 ошибка broccoli как исправить