Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add insert in JpaRepository [DATAJPA-1707] #2003

Closed
spring-projects-issues opened this issue Apr 3, 2020 · 6 comments
Closed

add insert in JpaRepository [DATAJPA-1707] #2003

spring-projects-issues opened this issue Apr 3, 2020 · 6 comments
Assignees
Labels
in: core Issues in core support status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link

hbourada opened DATAJPA-1707 and commented

We should have in addition to save an insert only method in JpaRepository to insert an entity if we want ensure creation of new entities without updating inadvertently a previous one:

<S extends T> S insert(S entity)


Affects: 2.0 Backlog

@spring-projects-issues
Copy link
Author

Jens Schauder commented

I don't see how this would work in a consistent way.

  • What should happen if the entity references other entities that already exist, but might be modified.
  • Should the entity be managed after calling insert? If it is it wouldn't really be an insert, if it isn't it would behave very differently from save.

There is one thing one could implement easily in a custom method if desired: performing a save after checking that the entity is new. But since it is hard, possibly even impossible, to make this consistent with JPA I don't think it would be a good addition for the JpaRepository

@spring-projects-issues
Copy link
Author

hbourada commented

Imagine we have 2 REST endpoints one for insert and other for update to distinguish the 2 operations , if the entity does not have a nullable technical identifier (example: Long) which simplify new entity state checking we can not implements this functionality using regular JpaRepository#save 

 

@Entity
class User {
@Id 
String username;
String password; ....
}

 

 

class UserService {
  UserRepository repository;
  void insert(User u) {
    repository.findById(u.getUsername()).ifPresent(u -> {throw new    IllegalArgumentException("..")});
   // if another parallel request insert same username and the 2 verify  //condition above => we can not ensure insert
    repository.save(u);
  }
}

if we have JpaRepository#insert(S entity) calling only EntityManager#persist(E e) I don't see where is the problem if user calling this method know what he is doing

 

 

@spring-projects-issues
Copy link
Author

Jens Schauder commented

we can not implements this functionality using regular JpaRepository#save

Yes you can: Just select it from the database, which is the same way JPA does it in these cases.

I don't see where is the problem if user calling this method know what he is doing

The "if" is the problem. Judging from Stack Overflow questions and similar sources suggests many, possibly the majority of the JPA users are not aware of the basics JPA entity lifecycle, 1st level cache and dirty checking. This means many users aren't even aware that there is a decision to make or an expectation to have.

As a case in point: the two question I asked still aren'd answered. Although I admit they are kind of rhetorical since I don't think there are good answers for this

@spring-projects-issues
Copy link
Author

hbourada commented

What should happen if the entity references other entities that already exist, but might be modified.

I don't see any problem, if referenced entity exist => we insert current created entity id in the join table in case for a many-to-many relationship because for one to many we ca not have other entities already created (I don't see a real case).

 Should the entity be managed after calling insert? If it is it wouldn't really be an insert, if it isn't it would behave very differently from save.

if user modify an entity after a persist using a setter and current transaction is not commited it's a normal that persistence context execute an insert after an update (I ensure my affirmation by a test)

N.B.: Another point in spring data Mongo we have an insert method in MongoRepository

so for consistency is not a bad idea to add insert to CrudRepositoy

@spring-projects-issues
Copy link
Author

Jens Schauder commented

As laid out there is no clear way to make this work consistent with immediate expectations and the typical JPA behaviour.

It also doesn't match the model of a "repository" where you just add an aggregate and therefore we try to avoid such method where possible

@spring-projects-issues
Copy link
Author

Jens Schauder commented

Regarding consistency with other repositories: The addition to the MongoRepository is probably considered a mistake and in the JDBC module we explicitly reverted a change introducing an insert method although it is definable in a consistent way in that module.

@spring-projects-issues spring-projects-issues added status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement in: core Issues in core support labels Dec 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core support status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants