-
Notifications
You must be signed in to change notification settings - Fork 2.9k
exists() method for repository #7884
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
Comments
Is it really that common to check for existence of a record without loading it? I've never had to do that myself. |
@FroMage but isn't it too much to load all fields from db to check if it exists? |
Well, sure, but only if you need to check for existence without later using the entity. I've never seen such a use case. All my use-cases check if the object exist and then proceed to use the entity. |
@FroMage yeah, it makes sense. In my case, I check the record exists. If it does, I throw a custom exception. |
@FroMage I also sometimes just check for existence in my apps, and then throw an NotFoundException. If you want, I can try to implement this feature. |
But if it exists, what does it do? |
I use "exists" to prove if an id really refers to an existing aggregate when i only hold the id in another aggregate. It is a business rule in our system so i have to check it but i do not need the hole entity, only the already given id. |
note that count is not too far from what you have in exists.
if ( !Person.exists(1L) ) { ... }
// vs
if ( Person.count("id", 1L) != 1 ) { ... }
…On Sun, Mar 29, 2020 at 9:36 PM Alexander Dammeier ***@***.***> wrote:
I use "exists" to prove if an id really refers to an existing aggregate
when i only hold the id in another aggregate. It is a business rule in our
system so i have to check it but i do not need the hole entity, only the
already given id.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#7884 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACJNWA7GUI7XQLGT4FREGDRJ6PLLANCNFSM4LMFG6LA>
.
|
But is exists faster? edit: |
What do you want for the feature? The existence of the entity? Or the existence of some column value? The one annoyance with my solution is that the user must know that the id property is named "id" |
👍 to implement this, I think that of course you can do a |
Postgres example:
Now imagine that name has no index on it (on purpose), and request results in a full-table-scan. Count will have to actually scan the whole table, while |
Sure, but the question remains: what do you do once you know the entity exists? |
The question is not what "to do", the question is what "not to do". For example:
Of course, race condition is still possible unless you raise transaction isolation level, but then it would be rare enough so I just can refer to low salary, unreasonable deadlines, and bad management in general to justify why my code has sporadic issues. |
My argument was that in most cases, once we know the entity exists, we typically load it. For example, if you want to avoid creating a duplicate, you check that it exists, but then… what do you do with the object you wanted to create? Don't you turn the insert into an update? For that you'll need the entity. I'm only trying to get a better idea of the usefulness of this. I can believe it's more efficient than count, for sure. That's one argument in its favour already. I didn't understand yet how useful it can be to check for something's existence and if it exists, not need it. If it doesn't exist, there's no problem, of course. |
In our case, we often check for the existence of an entry because the existence alone tells us if a step in our process was executed successful. Otherwise we schedule a retry, so for this case we use it more like an event store and the entries are often immutable. I think it is very dangerous to use an exist function to avoid duplicates as another process could create such an entry after you just checked it. In my opinion, unique constraints (ID conflicts) are the only viable option to truly avoid this and therefore we always check if the transaction failed because of a conflict. We then do not load the entry because knowing that it exists is enough to continue or there is simply nothing left to do. |
Our company has a microservice architecture which also uses Kafka for communication. |
@gavinking is there an equivalent |
No, and what would the semantics of such an operation be?
|
But the main reason we don't have it is it's typically such a crappy and inefficient way to interact with the database. |
Probably the people who want this should be using |
So, to be clear (I was posting from my phone). The people posting above are giving what looks to me like terrible advice on how to implement an upsert on databases which don't support the SQL The approach Hibernate uses to emulate
An alternative approach is to attempt the The following is not a good solution:
Anyway, people don't need to be implementing this stuff themselves, since it's already implemented by |
And this is terrible.
I'm on my knees begging everyone to put down the DDD Jonestown Kool-aid and just try using JPA and your relational database in the normal way that these things were intended to be used. |
Again, in our distributed system (hospital), we receive a lot of Kafka messages - only a small part of which is relevant for our app. @gavinking - I see your point and I also read that others just need an upsert, but I'd like to believe that we actually have a legitimate usecase for this exists check. |
Yeah, agreed. I was sceptical because I assumed I am not sure if it's a common use-case, though. But at least it's new to me :) |
@markus-lehr-dedalus In your use case, what are the transactional semantics of that? |
Another comment: in the case where (Unclear to me why |
@gavinking I'm not 100% certain what you mean by transactional semantics, but I can give you a workflow: One of the specific workflows (simplified a bit) for us is that we get the Kafka message for any medical case update ( After a bit of validation, we enter a method marked as If we find any entity, then we know that we have to process the message's content further and create or update another whole different entity (physical location relevant for nurses) than the one we executed the If we don't find any entity (e.g. patient came in for something unrelated to blood samples), then we don't create any entity and the transactional method ends. |
And then you retry later? |
No we don't retry later - the producers of the Kafka messages write to general purpose topics and consumers can subscribe to those changes. Imagine in the hospital someone shouting "Someone stubbed their toe!", but we might not be interested in this event. Whether or not we are interested - again - is written in our DB and can change at runtime. You probably mean: If such an entity (which indicates we might have been interested in a medical case update) is created at a later point, then we must have missed those updates? Then we fetch the current information for the nurses via REST in a separate mechanism. See my attached impeccable ms paint diagram for clarity. |
So, look, since we already opened the door by adding boolean exists =
session.createSelectionQuery("where key = ?1", Thing.class)
.setParameter(1, key)
.hasResults(); And the resulting SQL would be: select 1 from things where key = ? limit 1 But honestly I'm just not clear on how generally-useful this would be. I mean, you can already write: boolean exists =
sesssion.createQuery("select 1 from Thing where key = ?1 limit 1", int.class)
.getSingleResultOrNull() != null; which is really not much worse. @FroMage ? |
@gavinking I like your proposed solution because of the enhanced expressiveness - however, I totally understand that not a lot of people will use this. |
For Panache, this would be: // assuming we're talking about a Panache query and this is not a primary key
boolean exists = Thing.exists("key", key); Or for a primary key: boolean exists = Thing.existsById(key); I can trivially implement the first one (query) by using the first example As for the second case (by id) the translation is not trivial, I think. |
Generalizing over all SQL databases is definitely above my pay grade. I suppose the main alternative would be: select exists(select 1 from Thing where key = ?1) I just asked ChatGPT, and it claims that they are equivalent on Postgres, and recommends use of |
I suppose it means I have to reopen this to support this new method :) |
Uh oh!
There was an error while loading. Please reload this page.
Description
Nowadays we have the
findByIdOptional
andcount
to check if a record exists inside the database.count
is much faster than selecting the whole object data and serializing it. But wouldn't it be nice to have anexists(id)
method to abstract a db query that is so common?The text was updated successfully, but these errors were encountered: