How to save object nested inside another object with ormlite? - java

I try to save "BestandItem", which is made out of "ScanItem" and a Calendar with Ormlite. After I restart my app (for Android with Android Studio, which I write with Java) the content of ScanItem is gone, but only if it is inside of a Bestanditem.
This is my ScanItem:
#DatabaseTable(tableName = "scanItem")
public class ScanItem{
#DatabaseField (generatedId = true)
private int id;
#DatabaseField
private String barcode;
#DatabaseField
private String name;
public ScanItem(String barcode, String name) {
this.barcode = barcode;
this.name = name;
}
public ScanItem(){}
And this is my BestandItem:
#DatabaseTable (tableName = "bestandItem")
public class BestandItem {
#DatabaseField (generatedId = true)
private int id;
#DatabaseField (foreign = true, foreignAutoCreate = true)
private ScanItem scanItem;
#DatabaseField (dataType = DataType.SERIALIZABLE)
private Calendar ablaufDatum;
public BestandItem() { }
public BestandItem(ScanItem scanItem, Calendar ablaufDatum) {
this.scanItem = scanItem;
this.ablaufDatum = ablaufDatum;
}
Some of the things I have tried:
- Ormlite Documentation
- First Stackoverflow Answer
- Second Stackoverflow Answer
For more code see my github project: Github SmartFridge
My Ormlite Database has a UtilConfigClass and a always updated config.txt.
What did I do wrong here? Why dosn't save the ScanItem right?
After some checks, I can say that the other methods work just fine. (only after the lost of the ScanItem, I get NullPointerException). My conclusion is, that the problem is the constructor of the BestandItem.
I think I did something wrong with generatedID and/or foreignAutoCreate, but I dont really understand how do use it properly.
Also what exactly foreignAutoRefresh does.
I have tried to change the ID and generatedId around, because I think there lies the problem.

After some tests and countless trys, I now have a solution.
Because the barcode inside of ScanItem is unique, I could use it for a ID, instead of a generated id.
And with an existing ID, the programm now works.

Related

Question about Springboot, mongoDB relations and API

So I'm trying to create a project based in some weather forecast API and the data comes in different objects like:
public class WeatherForecast{
private String local;
private int maxTemp;
private int minTemp;
private int precipitationId;
}
public class Precipitation{
#Id
private int id;
private String descriptionEn;
private String descriptionCh;
...
}
So, I want to store this information and obtain the description of the Precipitation in the language that I desire, without receiving an WeatherForecast with the description of 10+ languages.
I searched a lot about defining relations between the tables but I couldn't find something related to relationships by id's. I found that I could use,
#DbRef
private Precipitation precipitation;
but I couldn't understand how it can interpret the Id without passing in the constructor.
And, finally, I want to understand if it's a good practice to send the two objects
separately to the database and try to workout some functionality to get the object I want, something like this:
public class WeatherForecast{
private String local;
private int maxTemp;
private int minTemp;
private String description;
}
using criteria, queries, or other things without extracting the two tables and searching in Precipitations for the desired description language.

Whats the best way to sum up multiple GET-requests in one single request?

I have the following entity:
#Data
#Entity
public class DailyEntry {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private LocalDate date;
private LocalTime startTime;
private LocalTime endTime;
private Duration breaks;
private String performanceRecord;
private EntryStatus status;
#ManyToOne
private Project project;
#ManyToOne
private Employee employee;
}
In the RepositoryRestResource i have the following method defined:
#PostFilter("hasRole('ROLE_BACKOFFICE') or hasRole('ROLE_ADMIN')")
List<DailyEntry> findByProjectId(#Param("id") Long id);
Im able to call that API-method with the following URL for example:
http://localhost:8080/api/dailyEntries/search/findByProjectId?id=1005
This will return all dailyEntries whose project has the id 1005.
Thats how i call it on the client site:
projects.forEach(project => {
const httpParams = new HttpParams().set('id', project.id.toString());
const dailyEntriesObservable = this.dailyEntryService.search('findByProjectId', httpParams);
// the definition of the search method is not important
});
The problem is that in some cases i have around a hundret(and more) projects which resulsts in a hundret(and more) requests which slows things down. Instead of doing a request for every single project, i would like to do one single request for all projects. Should i just send the Ids of the project in the RequestBody? How would the URL look like? Would it be something like http://localhost:8080/api/dailyEntries/search/findByProjectIds with the Ids being in the RequestBody? Ive never seen such a GET-request, so im not sure how the standarts here are for the REST-URL-Design or whether im doing something wrong and theres actually a better way to do it.

How do I use DynamoDBAutoGeneratedKey to give me an auto generated key?

I need to use DynamoDBAutoGeneratedKey from the AWS SDK to give me a random key(of type String) that I can then use to do something. I can't find any examples online of doing this, and while it seems like it should be relatively straightforward I am really struggling to get this working. Can anyone link me to an example of this being used?
Found easy answer.
String uniqueID = UUID.randomUUID().toString();
Screw using DynamoDBAutoGeneratedKey, sounds like a headache.
#DynamoDBTable( tableName = "Details")
public class Details
{
#DynamoDBGeneratedUuid( DynamoDBAutoGenerateStrategy.CREATE )
private UUID id;
....
#DynamoDBHashKey(attributeName = "id")
#DynamoDBAutoGeneratedKey
public UUID getId()
{
return id;
}
// also you need to add the setter otherwise you will get an exception
public void setId(UUID id)
{
this.id = id;
}
...

OrientDB: delete record and references created with Object API

I am using the OrientDB 2.1.6 Object API.
I have two POJOs with a 1 to N relationship like this:
public static class Results {
private String userId;
private String templateId;
private Double totalLength;
private List<String> visibleFields;
private Boolean filterable;
#OneToMany(orphanRemoval = true)
private List<ResultItem> items;
//Generic getters and setters
}
public static class ResultItem {
private String id;
private String vsId;
private String entryTemplateId;
private String objectType;
private String objectTypeLabel;
private String capabilityComment;
private Boolean currentVersion;
private Double contentSize;
private String name;
private String objectStoreId;
private String mimeType;
private HashMap<String, String> attributes;
private Date dateLastModified;
//generic getters and setters
}
This creates two classes in OrientDB. If I delete a Results instance using the Object API, it will delete associated ResultItem rows correctly.
I am trying to delete a particular ResultItem record using the "console" like this:
orientdb {db=test}> find references #15:6392 Found
[{rid:#15:6392,referredBy:[1]}] in 0.014000 sec(s).
orientdb {db=test}> delete from ResultItem where #rid=#15:6392 Delete
record(s) '1' in 0.006000 sec(s).
orientdb {db=test}> find references #15:6392 Found
[{rid:#15:6392,referredBy:[1]}] in 0.014000 sec(s).
The console output suggests that the record has been deleted but it continues to contain a "reference".
This manifests itself as a problem when I go back to the Object api and try to db.detachAll(results, true);. It throws this exception which I assume is due to the the orphan relationship.
Caused by: java.lang.NullPointerException
at com.orientechnologies.orient.object.db.OObjectLazyList.convertAndDetachAll(OObjectLazyList.java:456)
at com.orientechnologies.orient.object.db.OObjectLazyList.convertAndDetachAll(OObjectLazyList.java:432)
at com.orientechnologies.orient.object.db.OObjectLazyList.detachAll(OObjectLazyList.java:424)
at com.orientechnologies.orient.object.enhancement.OObjectProxyMethodHandler.detachAll(OObjectProxyMethodHandler.java:165)
at com.orientechnologies.orient.object.enhancement.OObjectEntitySerializer.detachAll(OObjectEntitySerializer.java:261)
at com.orientechnologies.orient.object.db.OObjectDatabaseTx.detachAll(OObjectDatabaseTx.java:809)
at com.orientechnologies.orient.object.db.OObjectDatabaseTx.detachAll(OObjectDatabaseTx.java:327)
How can I delete the relationship along with the record?
I tried your case and I got your same results.
This is a limitation about the references because there's no check on #RID consistency and when you delete a document, the deletion of all references would activate a full scan of the DB to search all the documents linked to the first and then drop the references.
This would be a very expensive operation and it would take a lot of time, this is one the reasons because using edges is reccomended instead of the LINKS, LINKLIST,...
Hope it helps

Usage of Native SQL functions in ORMlite anotations

I am interesting in ORMlite usage in android application. But there is one problem.
The first step is to annotate your class, but I need something like this:
#DatabaseField(columnName = "geometry", useGetSet = true)
String JSONgeometry;
#Formula (nativeSQL = "ShapeFromJSONText(JSONgeometry)")
public void set(String JSONgeometry){
this.JSONgeometry = JSONgeometry;
}
#Formula (nativeSQL = "asJSONtext(geometry)")
public String get(){
return JSONgeometry;
}
Is there any way to insert native SQl functions in annotations? Is there any way to use BasePersister for solving this tasks?
Could you be more specific what functions ShapeFromJSONText and asJSONtext exactly do?
I feel from your approach that you want to save object in geometry field.
Create separate class in your model:
class Geometry {
#DatabaseField(generatedId = true)
int id;
#DatabaseField
float field1;
#DatabaseField
float field2;
}
In your parrent class refer to it like this:
class Shape {
#DatabaseField(foreign = true)
Geometry geometry;
}
Of course if you dont want to save object but just its JSON represenatation you can save it to the String field.
In case you want to use your SQL functions to change the saved object somehow you can do it in getter and setter too in Java.

Categories