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
In Java, How to Combine Two Json Arrays of Objects
Classcastexception Because of Classloaders
Delete Everything After Part of a String
Refreshing Existing Windows in Java Swing
Cannot Load Driver Class: Com.Mysql.Jdbc.Driver Spring Boot
Batch Inserts Using JPA Entitymanager
How to Find Out the Exact Requested Url in Servletrequest If That Url Contains Path Variables
How to Find Out If String Has Already Been Url Encoded
Json to Pojo With Nested Values
Create List of Object from Another Using Java 8 Streams
Using an Empty Keystore Password Used to Be Possible
How to Solve Maven 2.6 Resource Plugin Dependency
Replacing Double Backslashes With Single Backslash
Deserialization With @Jsonsubtypes for No Value - Missing Property Error
How to Encrypt a String/Stream With Bouncycastle Pgp Without Starting With a File
Type Safety: Unchecked Cast from Object to Arraylist<Myvariable>