-
Notifications
You must be signed in to change notification settings - Fork 30
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
insert and update methods #270
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey everyone, I understand there was a recent vote to do a git revert and implicitly include the insert and update methods in the Jakarta Data spec as dynamic methods. However, I'd like to encourage a thorough reconsideration of this decision for the following reasons:
-
Preserving Abstraction: The cornerstone of the Repository pattern is Abstraction, and it has historically encapsulated insert and update operations within the save method, as per our documentation. This design choice simplifies the API and keeps the core concept intact.
-
Dynamic Provider Extension: One of the strengths of the Jakarta Spec is its flexibility. By allowing providers to include these methods dynamically, we maintain the optionality of this feature. It aligns well with our spec's philosophy, where customization and adaptation are encouraged rather than enforced.
-
Consistency and Spec Clarity: If we proceed with inserting explicit insert and update methods, aligning our spec with this decision is crucial. Thus, I recommend renaming the Repository as a Data Access Object (DAO). Or include these methods as DAO capability in the next version.
In summary, my primary concern is that by introducing explicit insert and update methods, we might inadvertently dilute the essence of the Repository pattern. An analogy that comes to mind is creating an annotation for Singleton and then adding a feature to allow multiple instances of a Singleton. It could lead to confusion and undermine the core concept. Therefore, we should carefully consider the implications of this change and whether it truly aligns with the goals of the Jakarta Data spec.
P.S.: I am not saying the insert and update are unnecessary; just as with any pattern, it brings trade-offs.
* Indicates that an entity cannot be inserted into the database | ||
* because an entity with same unique identifier already exists in the database. | ||
*/ | ||
public class EntityExistsException extends DataException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even inserting and updating several NoSQL databases does not necessarily mean it will work as a relational database.
It might go to several databases that will work in the append model as some wide-column and key-value databases, for example, Apache Cassandra and som key-values databases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might go to several databases that will work in the append model as some wide-column and key-value databases, for example, Apache Cassandra and som key-values databases.
Thanks for pointing this out. Those types of databases don't offer the insert capability that guarantees you caused the entity to be created and so should raise UnsupportedOperationException
when the insert operation is attempted. I added commit 94c74b8 to explicitly state this in the spec and JavaDoc.
The If we are only interested at simplifying the API at the expense of functionality and performance, then we should also be asking why CrudRepository has methods like
Don't confuse flexibility with optionality. By offering
You're recommending to rename CrudRepository (CRUD = Create, Read, Update, Delete) to something else because we added |
As I said, I am not against the insert and update method, I am saying that it is not a repository anymore, because we are defining directly to the database. The spec is not forbidden, thus, the provider is free to include those as functions as extra features.
We are asking for a domain, we are not exploring direct command, a simple sample might be the Collection of Java. It provides count, returns information, and adds, and we do not know where the information came from, that is the beauty of abstraction. The huge point would be to read the book.
I am not against insert and update, as I said with a singleton with multiple instances. We can use multiple instances, but it is not a singleton pattern anymore.
The save method can do both by abstraction, the CRUD is there where there are situations where the provider inserts and other can provider update, if the user can do it directly, they can use the DAO pattern. IMHO: We could also discuss it more in the next release version as the next pattern to cover. |
That is not true. I haven't defined insert and update in terms of the database. In this pull I defined an operation that must create something anew and another operation that modifies something that already exists. That is not database details. They are very useful patterns to write business logic around.
Since you bring it up, let's take a look at the Collection.add method. As a user of a Collection, I don't know if invoking
That is not true. The |
I still don't agree in any way with the counterargument that is being made against having @otaviojava please review da02bb7 removing |
Signed-off-by: Nathan Rauh <[email protected]>
…oved from CrudRepository
c9b5f89
to
da02bb7
Compare
Let's take one step back on this discussion. I am not against insert and update methods; those are very useful! We both agree that insert and update are super critical for the user! What we need to define is the bundle around patterns. What do you have in mind for the API in the future? Do you see putting those features here breaking into small pieces or having a package for each pattern? Because we can redefine it as a Facade instead of a Repository as we are doing now. |
Please, don't get me wrong, let's discuss more about it. It is more related to the API future than the insert and update method; as I said, those are crucial. I see how it fits in the API's subsequent versions. Doing a ballparking in persistence patterns, I can see those beyond Repository that might come in new versions:
What I do in my mind is to have a domain for each pattern instead of putting all of those into a single interface, currently called CrudRepository. What do you have in mind for Jakarta Data's following versions? It is more to define bundles of each pattern we might have in the future instead of having all those into a single point. |
Yes, that's smart to look ahead toward future plans to ensure what we are doing now is consistent with it. I agree we wouldn't be adding all these other patterns onto CrudRepository. CrudRepository should only cover the basic CRUD operations (Create, Read, Update, Delete) that a user would expect from something with CRUD in its name. If you are agreeing to put the methods back onto CrudRepository, let me know and I can put them back. Otherwise, review this PR without them and further discussion can continue about whether they can be included or if CrudRepository needs to be renamed because it isn't CRUD without them. |
For you, what is the difference between a DAO and a Repository? My point is, in a repository, we are doing it, but not as imperative; we explore the save. The user doesn't have this control. DAO is where we should have inserted, and updated methods, and we should not have the save methods. |
You're pointing out it's not a repository if we include create and update operations on it, and I'm pointing out that it isn't CRUD if we don't. In last week's meeting it was decided that we would include all of (insert, update, save), to give the user the most flexibility to use whichever pattern they want, and that's how this pull was originally written. I realize the different patterns won't be purely followed if a user intermixes them. Many users don't care as much about purely following patterns as they do being able to achieve what their business logic requires. I don't see that as a problem. |
If everyone else believes it's more important to adhere to a pure repository pattern than to offer all of the CRUD operations (although it didn't seem that way on the last meeting), then we should rename CrudRepository to something else, maybe BasicRepository, and stop claiming it provides CRUD. If that needs to happen, it doesn't belong under this pull because this pull no longer touches the CrudRepository. This sort of debate should not be happening here and is just holding up progress. |
I like the BasicRepository approach. |
Yes, I liked the proposal of renaming it to "BasicRepository" if it makes it more accessible and avoids the CRUD expectative. You have a good point: users sometimes do not care about it, mainly to archive business requirements. But, by default, the standards keep moving to the proper path. Such as in the EJB Singleton annotation guide to a unique instance, at CDI ApplicationScope being to the scope of the application, at JAX-RS GET annotation to HTTP get, and so on. |
@otaviojava Abstraction is always a nice thing to have when two things are fundamentally the same. But when you try to abstract over things which are just too different from each other, you get in a mess. "Make persistent" and "update" are different operations even in Jakarta Persistence, where we're dealing with just one sort of technology. Believe me, if there were a reasonable way to abstract over these operations with one single method, we would have designed Jakarta Persistence to work that way! Now if we start to consider other of technologies, we'll find that "save this change" has different semantics again. For example, I can imagine that one single "save" method actually might indeed make sense in a document database. (But I am definitely not an expert on the topic of document databases!) So I think Jakarta Data needs to own up to these differences, instead of trying to sweep them under the rug. |
@otaviojava I think you need to consider that in my proposal, where there is an abstracted notion of "lifecycle methods", which are specialized by an extensible set of lifecycle annotations, that you don't need to multiply the set of Your "basic repository" is just a repository with a lifecycle method with a |
This is obsolete now that the lifecycle annotations were introduced and documentation was put there instead. |
Add insert and update methods with an entity parameter.
This is split out separately from #266 , which covered save and delete with an entity parameter.