UnrecognizedPropertyException map to JSONObject - java

currently I am programming a stocks project for my Bachelor degree, but I'm stuck.
For Frontend I use Angular and Backend Java with a Postgres DB.
I'm getting a 500 response when I try to update a row in my DB. The error is
org.glassfish.jersey.server.ContainerException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "empty" (class org.json.JSONObject), not marked as ignorable (0 known properties: ])
In Angular I have a Watchlist Interface, which I want to update with an additional investment in it, send the new Watchlist to the backend, to store it in the db.
export interface Watchlist{
id?: number,
userid?: number,
watchlist?: any
}
on button click in the template I access the following method.
hinzufuegenWatchlist(){
this.mainComponent.watchlist.watchlist[this.isin] = this.investment;
this.watchlistService.sendRequestUpdateWatchlist(this.mainComponent.watchlist)
.subscribe(response => console.log('Investment zur Watchlist hinzugefĆ¼gt'));
}
sendRequestUpdateWatchlist(watchlist : Watchlist){
return this.http
.put<Investment>(this.getServiceURL().concat("updateWatchlist"), JSON.stringify(watchlist),this.getOptions())
}
In the backend I use a JSONObject for the watchlist. The idea is to store every investment with its isin as an accessible key, to easily check whether its already stored or not. And easily store the whole watchlist in one row in the DB:
public class Watchlist {
private int id;
private int userid;
private JSONObject watchlist;
#PUT
#Path("updateWatchlist")
#Consumes({MediaType.APPLICATION_JSON})
public void updateWatchlist(Watchlist watchlist){
try {
String sql = "UPDATE watchlistdb set watchlist=? where id=?";
PreparedStatement ps = DatabaseHelper.connectDatabase().prepareStatement(sql);
ps.setString(1,watchlist.getWatchlist().toString());
ps.setInt(2,watchlist.getId());
ps.execute();
} catch (Exception e){
e.printStackTrace();
}
}
My first thoughts are, that it can't be mapped because it isn't a standard Java type like string or int. But how can I solve that problem?
Thank you for your time and help!

Related

Is there a spring for graphql alternative for netflix's #DGSDataloader and DGSData

Trying to migrate a Netflix DGS GraphQL and Neo4J project to now use Spring for GraphQL and Neo4J instead. Hit a roadblock when I wanted to avoid the N+1 problem.
Yes, there is an alternative to avoid the N+1 problem in Spring for GraphQL. It's the #BatchMapping annotation:
Suppose you have the following schema:
type Query {
artistas: [Artista]
}
type Artista {
id: ID
apellido: String
estilo: String
obras:[Obra]
}
type Obra{
artistaId: ID
titulo: String
imagen: String
}
And the following #QueryMapping:
#QueryMapping
Flux<Artista> artistas(){
return Flux.fromIterable(allArtistas);
}
Our Artista DTO contains a List of Obra we may sometimes want, so it can cause us the N+1 problem:
record Artista (Long id, String apellido, String estilo, List<Obra> obras){}
record Obra (Long artistaId, String titulo, String imagen){}
So if you add an additional mapping method annotated with #BatchMapping, you tell the GraphQL engine to fetch that data using a DataLoader under the hood and keeping it at hand for each DB roundtrip, for example.
#BatchMapping(typeName = "Artista")
Mono<Map<Artista, List<Obra>>> obras(List<Artista> artistas){
var artistasIds = artistas.stream()
.map(Artista::id)
.toList();
var todasLasObras = obtenerObras(artistasIds);
return todasLasObras.collectList()
.map(obras -> {
Map<Long, List<Obra>> obrasDeCadaArtistaId = obras.stream()
.collect(Collectors.groupingBy(Obra::artistaId));
return artistas.stream()
.collect(Collectors.toMap(
unArtista -> unArtista, //K, el Artista
unArtista -> obrasDeCadaArtistaId.get(Long.parseLong(unArtista.id().toString())))); //V, la lista de obras
});
}
private Flux<Obra> obtenerObras(List<Long> artistasIds) {
// ...your service-specific way of getting all the Obras from each artistaId...
}
If you throw some logs here and there you can check it only fetches the Obras once.
Hope it helps!

How to mask out some field in grpc response when logging

I want to mask out some field when logging.
is there any good way to mask out?
after message is served to client.
I'm trying to mask out some field before logging
how do you mask out field?
--served to client
message {
id : "user",
phoneNumber : "12341234"
}
--logged response
message {
id : "user",
phoneNumber : "12******"
}
I don't think there is a way to alter the data like you mentioned, however there is a way to hide field that you don't want to print in the log (I assume its for security reasons). The way yo do that is with FieldMask.
So for the sake of the example I took the liberty of adding another field to the schema I assume you have:
message User {
string id = 1;
string name = 2;
string phone_number = 3;
}
So now let's say that I don't want to show the phone number of my users, I can use a FieldMask to keep only id and name. So first we build a FieldMask (you'll need to add this dependency for accessing FieldMaskUtil):
public static final FieldMask WITH_ID_AND_NAME =
FieldMaskUtil.fromFieldNumbers(User.class,
User.ID_FIELD_NUMBER,
User.NAME_FIELD_NUMBER);
then what I can do is merge this FieldMask with an existing object:
private static void log(User user, FieldMask fieldMask) {
User.Builder userWithMaskedFields = User.newBuilder();
FieldMaskUtil.merge(fieldMask, user, userWithMaskedFields);
System.out.println(userWithMaskedFields);
}
public static void main(String[] args) {
User user = User.newBuilder()
.setId("user")
.setName("a name")
.setPhoneNumber("12341234")
.build();
System.out.println("---Without FieldMask---");
System.out.println(user);
System.out.println("---With FieldMask---");
log(user, WITH_ID_AND_NAME);
}
This will give me the following output:
---Without FieldMask---
id: "user"
name: "a name"
phone_number: "12341234"
---With FieldMask---
id: "user"
name: "a name"
I hope that helps, let me know if you need more details, I can update my answer.

REST Service - org.hibernate.QueryException: could not resolve property error

I am trying to send data from my android app to my REST service so that it can be stored on a database. I have successfully done this in another app that I have worked on and when I am trying to do it with this project I am getting this error:
org.hibernate.QueryException: could not resolve property: line_type
In my Oracle Database the field is named "LINE_TYPE" and is VARCHAR2(20 BYTE).
Here is the code in my REST service table (which I have reverse engineered from my oracle database):
private String lineType;
#Column(name="LINE_TYPE")
#Size(max = 20, message = "Line Type has a max size of 20 characters.")
public String getLineType() {
return this.lineType;
}
public void setLineType(String lineType) {
this.lineType = lineType;
}
Also in my tableCriteria I have the getters and setters:
public String getLineType() {
return lineType;
}
public void setLineType(String lineType) {
this.lineType = lineType;
}
The last time I had this error it was through a spelling mistake or case sensitivity but I have double and triple checked and that is not the case here.
I have debugged the entity that the REST service is receiving in NetBeans and I can see that it is receiving the data. So why cant it be resolved?
Anyone see anything I don't?

Couchbaselite update operation leads to inconsistent behavior

I am using Couchbase Lite SDK for android and saving an object instance of MyClass as a document in the database. MyClass has an attribute that stores the date in the java.util.Date. During run time, I fetch all the instances of MyClass saved in the database and store them in the ArrayList<MyClass>. When I insert a new document into the database and read the values from the database to show all the entered instances, the date field saved in the database is retrieved as a Long when I next try to fetch the details from the database. The code I use to load the details from the database is:
Code snippet 1:
for (Field field: fields) {
field.setAccessible(true);
if (properties.containsKey(field.getName())) {
if ("date".equals(field.getName())) {
Log.d("DebugTag", properties.get(field.getName()) + "");
long dateLong = (Long) properties.get(field.getName());
details.setDate(new Date(dateLong));
} else {
field.set(details, properties.get(field.getName()));
}
} else if("_id".equals(field.getName())) {
details.set_id(document.getId());
} else {
final String msg = "Field " + field.getName() + " not present in document ";
Log.e(TAG, msg);
}
}
You can see that I have added an additional check in case the field is date. This works perfectly fine. So, I save a new entry to database and come back to the page where I see all the entries made into the database.
Now, I have implemented a new functionality to update the details of a record in the database. For updating the record I have the following implementation:
Code snippet 2:
public static boolean updateDocument(Database database, String docID, Map<String, Object> map) {
if (null == database || null == map || null == docID) {
return false;
}
boolean success = true;
Document document = database.getDocument(docID);
try {
// Have to put in the last revision id as well to update the document.
// If we do not do this, this will throw exception.
map.put("_rev", document.getProperty("_rev"));
// Putting new properties in the document ...
document.putProperties(map);
} catch (CouchbaseLiteException e) {
Log.e(TAG, "Error putting property", e);
success = false;
}
return success;
}
After doing this when I try to reload the items, it gives me exception while reading the date field in my Code snippet 1 saying that the Date object cannot be typecasted as Long and the application crashes. Now, when I again open the application, it works perfectly fine with all the changes to the edited entry reflecting correctly. Can anyone let me know the reason for this? I suspect, until we close the database connection, the changes are not committed to the actual database location and the date field in the updated entry is kept in the cache as the Date object in my case.
PS: Although, I have found a workaround for this by setting the date as a Long object in the payload (map in function updateDocument() in Code snippet 2), it would still be interesting to understand the problem I faced.
Looking at this further, this could be reasons related to auto-boxing where long to Long conversion of primitive types to the object wrapper class is crashing the application when trying to save.
Have you tried:
long value = Long.parseLong((String)...);
More specifically in Code snippet 1:
long dateLong = Long.parseLong((String)properties.get(field.getName()));

Oracle MAF : How to render ResultSet list into AMX page?

Logic: Display drop down (data from TABLE_ONE) in page1.amx and based on the selection it needs to get data from TABLE_TWO, then render the retrieved data into page2.amx. Below is the sample which I have tried,
I have created service class ServiceClass.java in my service package and created DataControl (ServiceClassDC) for that class.
From my FirstPage.amx I'm calling service class method using valueChangeListener in drop down (Drop down value will be populated from DB, let's take TABLE_ONE ID). Below is the piece of code for this logic,
FirstPage.amx
<amx:selectOneChoice value="#{bindings.selectId.inputValue}" label="Select Id" id="soc1"
valueChangeListener="#{ServiceClass.callThisMethod}">
<amx:selectItems value="#{bindings.selectId.items}" id="si1"/>
</amx:selectOneChoice>
Based on the selection using WHERE condition, I got the list of objects in productList which is having the result set data.
ServiceClass.java
public void callThisMethod(ValueChangeEvent valueChangeEvent) {
System.out.println("Selected Value: "+valueChangeEvent.getNewValue());
String selectedValue = valueChangeEvent.getNewValue().toString();
ClassMappingDescriptor descriptor = ClassMappingDescriptor.getInstance(TableTwo.class);
DBPersistenceManager pm = getLocalPersistenceManager();
try{
StringBuffer sql = pm.getSqlSelectFromPart(descriptor);
sql.append(" WHERE ID='"+selectedValue+"'");
sql = pm.constructOrderByClause(sql, descriptor);
ResultSet set = pm.executeSqlSelect(sql.toString(), new ArrayList());
System.out.println("Result set >> "+set);
List productList = pm.createEntitiesFromResultSet(set, (List) descriptor.getAttributeMappingsDirect());
System.out.println("productList "+productList);
} catch(Exception exp){
System.out.println("Exception : "+exp);
}
}
Now, I want to display the List object data (productList) into SecondPage.amx screen. How to do this?
Please comment below, if you want any more details regarding this.
You need to expose your List productList in a public method (so provide a get method) and expose that method in a Data Control. You can then drag and drop it on your page.
Example:
public Product[] getProductArray() {
return (Product[]) productList.toArray();
}
Note that this is an example from a MAF version where Java 1.4 was used!

Categories

Resources