searching for object with custom id - java

I have a class that looks like this
#Data
#NodeEntity
public class StoryCharacter {
#Index(unique = true)
private String agnosticId;
private String name;
#Relationship(type = "FAMILIAR_WITH")
private Set<StoryCharacter> acquaintances;
}
I needed a custom ID that is not related to the default long id. So I introduced a field and set it as index.
But how to find the object by that id?
I wanted to do it like this
session.openSession().load(StoryCharacter.class, "custom_id")
but it fails with error that it must be Long. I assume that maybe I need to use Filter object for search by that id. Or is there another way?

If you want to use a custom id the field has to be annotated with #Id instead of #Index(unique=true). In cases you do not want to set the id manually, there is an option to provide a id generation strategy (more details in the documentation.
You are seeing this error because Neo4j-OGM cannot determine what type your id field has and falls back to the standard Long. If you define your id as mentioned above, the load will work.

Related

Firestore - set a POJO field to the ID of the collection of a query

I know this is a very specific ask but I've got a situation where it would be very nice to have my custom class deserialized and have the collections parent ID set to a specific field. I know with the #DocumentId annotation we can do this for the documents own ID, is there some SDK method to extend this for my use case?
public class MyCustomClass {
#DocumentId public documentID;
...
#<insert magic here> public documentsCollectionsParentID
So for example, something like /users/<uid>/docs/<docid>, I already have the functionality for documentID to be set automatically to docID, but I'd like documentsCollectionsParentID set to uid. Is this in any way possible at the moment?
My current alternative is to deserialize, and the the object afterword:
MyCustomClass thing = (MyCustomClass)doc.toObject(MyCustomClass.class);
thing.setDocumentsCollectionsParentID(doc.getReference().getParent().getParent().getId())
Unfortunately, there is no method in Firebase that does that automatically. This is Java limitation and you are doing it correctly by deserializing the object.

Jackson generate id for saved references

In my project, class A references class B.
When saving an A using Jackson, I want to keep the reference to B, which is also saved.
To do that, I have a field called "id" in the referenced class and use this annotation:
#JsonIdentityInfo(scope = ReferencedClass.class, generator = ObjectIdGenerators.PropertyGenerator.class, property="id")
Doing this works fine when passing the id in the constructor, but I am creating an unknown number of ReferencedClasses.
Is there a way to make Jackson generate the id automatically?
And I wonder what the parameter generator = ObjectIdGenerators.PropertyGenerator.class means.
I did not find a solution that fit to this case, so in my main saveobject, I ended up using this code:
#JsonProperty private long generatedId = 0;
public long generateId() {
return generatedId++;
}
It works when using empty constructors and a proper #JsonTypeInfo if B is being extended.
I don't need generateId() anymore.
Using generator = ObjectIdGenerators.IntSequenceGenerator.class generated an id, which is only present in the JSON file.

Override Spring data JPA id annotation.

I'm using Spring-data-Jpa where I've an entity
#Entity(name="person")
public class Person implements Serializable {
#javax.persistence.Id
private long dbId;
#Id
private final String id;
// others attributes removed
}
In above class I've two different ids id (marked with org.springframework.data.annotation.Id) and dbId(marked with javax.persistence.Id) , since my id field is always populated with a unique identifier (for Person class which I'm getting from somewhere else) so while using Spring JpaRepository it always tries to update the record and since it's not in db, nothing happens.
I've debug code and saw that it uses SimpleKeyValueRepository which gets the id field which is id, and thus it always gets a value and tries to update record, can I override this behavior to use dbId instead of id field? Is there any way to achieve same with some configuration or annotation, any help is greatly appreciated.
Each entity must have exactly one #Id. On the other hand, you might want to declare a column as unique. It can be done by:
#Entity(name="person")
public class Person implements Serializable {
#Id
private Long id;
#Column(unique = true)
private final String uuid;
// others attributes removed
}
Also remember, that Spring Data JPA id should be reference Long instead of a primitive as you want to save objects with id = null.
String id should probably be String uuid and be initialized as String uuid = UUID.randomUUID().toString();
Similar situation would be an unique email requirement for user. On one hand it'll be a primary key, but on the other, you won't mark it as #Id.
If you need further clarification or your environment is more complicated, just ask in comments section below.

How to use 'id' when using DocumentDB via MongDB API in Spring DATA?

I have used both the ways of mapping _id as described in the Spring Docs here.
using #Id annotation
having a field with name id without any annotation
in my previous project where we used MongoDB as database and Spring Data for DAO operations. It worked without any problem for both String a well as for BigInteger.
Now we are using DocumentDB with MongoDB API(as Spring Data does not support DocumentDB).
I am able to use all the Spring Data methods, but I am not able to use custom id.
Below is my entity:
public class S{
private String id;
/* other fields here */
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/* getters and setters for other fields */
}
This is the DAO:
public interface SDao extends MongoRepository<S, String> {
}
Now if anywhere in my code I do:
s = new S();
s.setId("some-id-here");
The record gets successfully persisted in the DB with custom id some-id-here as String (not ObjectId), but after that it throws ClassCastException saying Long cannot be converted to Integer.
Same is the case when using BigInteger for id.
If I am not setting the custom id, i.e. I comment the setting of id as below:
s = new S();
// s.setId("some-id-here");
no exception is being thrown, but the record is being persisted with a random id provided by database itself as ObjectcId.
I want to save the record with custom id, so that I can easily update it when needed.
Currently if I have to update a record, I need to retrieve it using a key which is not mapped to _id and then update it and then delete the old record from the DB and then persist the updated one, which I feel is absolutely inefficient as I am not able to make use of _id.
My question is why am I getting ClassCastException, that too mentioning Conversion of Long to Integer
Is DocumentDB internally doing some conversion which is throwing this exception. If yes, how to tackle it? Is this a bug?
One alternative could be to let DocumentDB/ MongoDB create those IDs for you by default. In your class you can have another field which can serve as natural ID and create a unique index on that field for fetch optimization.
Refer https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/ for indexes.
The id generation rules are explained here link

Is there a way to use Mongo/Morphia without org.bson.types.ObjectId?

Morphia is a persistence library for the JVM, used when your app needs to communicate with a MongoDB. When you use it, apparently in Mongo/Morphia land, this unique ID needs to be a org.bson.types.ObjectId.
Is this true? Is there any reason why I can't use a Long for the ID, such as in:
// Groovy pseudo-code
#Entity
#JsonIgnoreProperties(ignoreUnknown=true)
#JsonInclude(JsonInclude.Include.NON_NULL)
class WidgetEntity {
#Id
Long id
// ...etc.
}
If it is possible to just use a Long, then what am I giving up by using a Long instead of an ObjectId?
You can use a Long but in this case you need to assign a value yourself.
From the morphia quickstart sample:
Also note that we had to add a new field "id" to our Hotel class. The
"id" value can be any persist-able type; like an int, uuid, or other
object. If you want an auto-generated value just declare it as an
ObjectId. If you don't use an ObjectId you must set the value before
saving.

Categories