In old version, SDN3, I can use findById(List id), but after upgrade to SDN4, I cannot use this function again, always return empty.
This is my sample class :
#NodeEntity
public class Right{
#GraphId
Long graphId;
String id; //random generated UUID
String name;
//Properties & Constructor
}
And then I have RightRepository that contain these code :
public interface RightRepository extends GraphRepository<Right> {
List<Right> findById(List<String> id);
}
Instead of use Loop to get per ID, I need to call repository only once, and get the List (without using findAll())
Is SDN4 already not support it? Is there any other solution?
As I post in a comment and after a further investigation, I think that a custom query is the only way to accomplish your requirement at the moment. This works:
#Query("MATCH (n:Right) WHERE n.id IN {rightIds} RETURN n")
List<Right> findRightById(#Param("rightIds") List<String> rightIds);
Hope it helps
Related
I have entity Article I'm trying to retrieve one random record from database collection.
This is entity Article:
#Data
#Document(value = "article")
public class Article {
#Id
private String articleId;
private String title;
private String description;
private String fullArticle;
This is service to save it:
#Override
public Article save(Article article) {
return articleRepository.save(article);
}
And repository:
#Repository
public interface ArticleRepository extends MongoRepository<Article, String> {
}
So, now I'm trying to create a method that will get me one random record from my collection Article also, I want to create a controller so when I go to some endpoint and submit some get method to retrieve one record from the collection and so I can check it in postman or with Swagger. I find some answers to similar question to mine but no one solved my problem, I want to have API for something like that.
You can use $sample in an aggregation query to get a random document:
db.collection.aggregate([
{
"$sample": {
"size": 1
}
}
])
Example here
I've tested the code and it works as expected.
You can create add this method into repository:
#Aggregation(pipeline={"{$sample:{size:1}}"})
AggregationResults<Article> random();
And call from service like this:
#Override
public Article random(){
return articleRepository.random().getMappedResults().stream().findFirst().orElse(null);
// also you can use .orElseThrow() or whatever you want
}
I use the below libs
quarkus-hibernate-orm-panache
quarkus-agroal quarkus-jdbc-mysql
quarkus-resteasy-jsonb
quarkus-resteasy
rest-assured
My #Entity
public class Products extends PanacheEntityBase implements Serializable{
private static final long serialVersionUID = 2L;
#Id
#Column( name = "id" )
public String id;
public String name;
public String description;
}
My Resources
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Products> getProducts() {
return Products.listAll() ;
}
With "quarkus-resteasy-jackson" I get
[{"id":"0b3d7518","name":"tests org","description":null},{"id":"78787518f","name":"ci tests org 2","description":"some text"}]
vs
With "quarkus-resteasy-jsonb" I get
[{"id":"0b3d7518f3","name":"tests org"},{"description":"some text","id":"78787518f","name":"ci tests org 2"}]
Question ?
If I use, quarkus-resteasy-jackson, it returns null value as a part of response. while quarkus-resteasy-jsonb does not return columns with null value as a part of response. "description" is not there in the response for id:0b3d7518f3. I need all fields. How can I achieve it. ?
Jackson order of json nodes is "id, name, description" the way I ordered in Entity. While JsonB it is "description,id,name". It is using sorted keys. Is there a way to override it in json?
Thanks
Well, I would say you answered the question yourself: if Jackson fits your needs, just use Jackson.
If you really want to use JSON-B, you can configure JsonbConfig with a JsonbConfigCustomizer bean.
See https://quarkus.io/guides/rest-json#json-b .
You can require the null values for sure and also tweak the ordering.
#Guillaume Smet above answer did help me solve it. Here is the code in case others are looking to..
#Singleton
public class MyJsonbFormatConfig implements JsonbConfigCustomizer {
public void customize(JsonbConfig config) {
config.withNullValues(true);
}
}
For ordering, here is the JsonbConfig property.
config.withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL);
Using Jackson with Retrofit, I wanted to have list of friends set to friendToMany during Deserialization. As I have gone through with documentation, we have to manually assign that entity to boxstore when assignable=true is set. So, I am doing this way(as shown in code). This approach works only for first item which this code is part of. It doesn't work for element 2 or further.
#Id(assignable = true)
#JsonProperty("_id")
public long id;
#Transient
private List<Friend> friends = null;
#JsonIgnore
#Backlink(to = "demoResponseToOne")
ToMany<Friend> friendToMany;
#JsonProperty("friends")
public void setFriends(
List<Friend> friends)
{
this.friends = friends;
for (Friend friend : friends)
{
MyApplication.getBoxStore().boxFor(Friend.class).attach(friend);
friendToMany.add(friend);
}
}
Exception thrown is : io.objectbox.exception.DbDetachedException: Cannot resolve relation for detached entities, call box.attach(entity) beforehand. at the time of add(friend). I mean this works when this Root element is first item of list.
You need to attach the Box<Friend> to this as well, which owns the ToMany to be modified:
MyApplication.getBoxStore().boxFor(Friend.class).attach(this);
Background: If you are using #Id(assignable = true) you need to take care of some things that ObjectBox would normally do for you. This includes attaching the Box before modifying any ToMany.
Source:
https://docs.objectbox.io/relations#updating-tomany
https://docs.objectbox.io/advanced/object-ids#self-assigned-object-ids
Now, I have the next entity. This one is the m1 table of my database.
#Entity(name = "m1")
#Data
public class Information {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String date;
private Double weight_1;
private Double weight_2;
private Double weight_3;
private Double weight_4;
private int working;
}
So, when I do some call to the APIRest it returns me the information corresponding to the m1 table. The controller that I have is the next (simple controller that returns all the information):
#Controller
#RequestMapping(path = "/information")
public class InformationController {
#Autowired
private InformationRepository repository;
#GetMapping(path="/all")
public #ResponseBody List<Information> getAllInformations() {
// This returns a JSON or XML with the users
return repository.findAll();
}
}
The question is: There is any way to change the name of the m1 on runtime. For example can I put the name of the table in the call path and in the API Rest take it?
Maybe this is impossible and I am doing it the bad way I do not know.
EDIT: I mean, can I change the table that the API Rest is taking the data by putting the table that I want in the url/path that I call. For example: in my case the default table/entity that the APIRest take the data is m1, so can I call http://localhost:8080/information/especifictable/all/ where especific table is the table that I want the recieve the data of the database and in the API Rest take that url parameter and change the default m1 with the especifictable.
I do not know if I have explained it well, I do not know how to explain it well.
Such a design would only make sense, if there are two tables in DB, which look the same. if that is the case there is something wrong with your DB design.
Basically it is not possible, to the best of my knowledge.
I am conducting some Neo4J tests and running into the following peculiar problem. I created a small model which I'm intending to use with OGM. The model has a superclass Entity and a child class Child. They're both in package persistence.model. Entity has the required Long id; with matching getId() getter.
public abstract class Entity {
private Long id;
public Long getId() {
return id;
}
}
#NodeEntity
Child extends Entity {
String name;
public Child() {
}
}
Creating Child objects and persisting them through OGM works fine. I'm basing myself on the examples found in the documentation and using a Neo4jSessionFactory object, which initialises the SessionFactory with the package persistence.model. The resulting database contains objects with proper ID's filled in.
The problem arises when I try to fetch a Child for a given ID. I'm trying it with three methods, using two connection systems (bolt and ogm):
boltSession.run("MATCH (a:Child) WHERE id(a) = {id} RETURN a", parameters("id", childId));
ogmSession.query("MATCH (a:Child) WHERE id(a) = $id RETURN a", params);
ogmSession.load(Child.class, childId, 1);
The first two methods actually return the correct data. The last one returns a null value. The last one, using OGM, has some obvious benefits, and I'd love to be able to use it properly. Can anyone point me in the right direction?
In your test code you are doing a lookup by id of type int.
private int someIdInYourDatabase = 34617;
The internal ids in Neo4j are of type Long.
If you change the type of the id to long or Long then it will work.
private long someIdInYourDatabase = 34617;