Crudrepository and Hibernate: Save(List<S>) VS Save(Entity) in Transaction

CrudRepository and Hibernate: save(List<S>) vs save(Entity) in transaction

From SimpleJpaRepository:

@Transactional
public <S extends T> List<S> More save(Iterable<S> entities) {

List<S> result = new ArrayList<S>();

if (entities == null) {
return result;
}

for (S entity : entities) {
result.add(save(entity));
}

return result;
}

So, your second business method only shadows save(Iterable<S> entities) Crud Repository method, in the sense that it iterates the list and calls save(S) on your behalf.

As long as transaction is demarcated from your processData business method, there is no really a difference in performance or queries executed.

Save(List<S>) vs save(Entity) in transaction part two

Methods provided by CrudRepository are already transactional.

This is not needed at all, just take a look at this implementation. All the methods delete, deleteAll,saveAllare annotated with@Transactional`. This means, that default implementation already takes it into account.

Actually whereever there is no @Transactional annotation, the default @Transactional(readOnly = true), that is on the class level is used.

Is CrudRepository.save(Iterable<S>) is atomic?

Behind the seen this is what's happening in case of SimpleJpaRepository save method with Iterable

@Transactional
public <S extends T> List<S> More save(Iterable<S> entities) {

List<S> result = new ArrayList<S>();

if (entities == null) {
return result;
}

for (S entity : entities) {
result.add(save(entity));
}

return result;
}

It's worth noting that save with Iterable has changed to saveAll in latest versions
Refer changes for more detail

What will happen if I save 10 entities and it fails for 6th one?

By default CrudRespository will have @Transactional so on case of exception nothing is saved.

In case of handling manually this will work

If you are doing something like this things will be rollback.

@Transactional(rollbackFor=RuntimeException.class)
public List<Car> saveAllOrNone(List<Car> cars) {
for(Car car: cars) {
repo.save(car);
}
}

Spring Data JPA save list entity return list in same the order?

In that version an actual List is the return type:

@Transactional
public <S extends T> List<S> save(Iterable<S> entities) {

List<S> result = new ArrayList<S>();

if (entities == null) {
return result;
}

for (S entity : entities) {
result.add(save(entity));
}

return result;
}

so if you pass a List to the method, you will get the result in the exact same order as the ArrayList is the implementation.

Spring data save vs saveAll performance

Without having your code, I have to guess, I believe it has to do with the overhead of creating new transaction for each object saved in the case of save versus opening one transaction in the case of saveAll.

Notice the definition of save and saveAll they are both annotated with @Transactional. If your project is configured properly, which seems to be the case since entities are being saved to the database, that means a transaction will be created whenever one of these methods are called. if you are calling save in a loop that means a new transaction is being created each time you call save, but in the case of saveAll there is one call and therefor one transaction created regardless of the number of entities being saved.

I'm assuming that the test is not itself being run within a transaction, if it were to be run within a transaction then all calls to save will run within that transaction since the the default transaction propagation is Propagation.REQUIRED, that means if there is a transaction already open the calls will be run within it. If your planning to use spring data I strongly recommend that you read about transaction management in Spring.

I can't do .save() with CrudRepository, error in @Id

use repository.saveAll(listObjects); instead of repository.save(listObjects).

private void saveDataExcel(List listObjects, CrudRepository repository) {
try {
repository.saveAll(listObjects);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

also correctly specify generics to your CrudRepository do something like:

public interface TbGdosRepo extends CrudRepository<TbGdos, String> {

}

and this kind of errors can be caught while compiling.

Spring Data JpaRepository saveAndFlush not working in @Transactional test method

The transaction which is opened for the test is rolled back at the end of the test method.

This can be disabled:

@Rollback(false) // <-- !
@Test
public void myTest()

Spring boot test @Transactional not saving

Also note that the ORM (e.g. Hibernate) will probably have some caching in place, which can prevent actually hitting the DB when querying within a transaction for a known entity.

So to test the successful persistence of entities it is good practice to test the retrieval in a separated transaction.

Why save() is necessary in Spring Data?

I'd say that this text you cite is just a good practice - it enhances the code readability / maintainability, i.e. remember that if you detach an entity within a @Transactional method, this entity won't be persisted. And explicitly stating the persisting of an entity is pretty much self-explanatory for the developer (or causes exceptions in case of mentioned detachment, which is self explanqtory as well).

I'd say that this consistency you were asking about means exactly that, at least for me. Being consistent meaning explicitly implementing a method that would be invoked anyway ("under the hood", which most often leads to bugs).



Related Topics



Leave a reply



Submit