NoClassDefFoundError can't get data from azure table - java

I am trying to read data from an azure table using the below code in an android project.
TableQuery<Observation> rangeQuery =
TableQuery.from(Observation.class)
.where(combinedFilter);
Iterable<Observation> results = cloudTable.execute(rangeQuery);
// Loop through the results, displaying information about the entity
for (Observation entity : results) {
res.add(entity);
}
As soon as I try to enumerate results it throws java.lang.NoClassDefFoundError: com.fasterxml.jackson.core.JsonFactory exception.
A table entity looks like this:
{"PartitionKey":"temperature",
"RowKey":"2014-12-19 23:15:19",
"Timestamp":"2014-12-19T23:15:20.2638537Z",
"humidity":38.0,
"temp":22.0,
"datetime":"2014-12-19 23:15:19"}
And the corresponding class is:
public class Observation extends TableServiceEntity {
String temp;
String humidity;
String datetime;
String PartitionKey;
String RowKey;
String Timestamp;
}
I suspect this is a serialization error. But I can't see anything wrong since all the properties are implemented in the Observation class.

Seems like the Azure SDK doesn't install one of its dependency. It can be downloaded from: jackson-core

Related

How to retrieve blob from server using JPA repository in spring

I've created spring application for CRUD. I can easily write into server data like string,Long,blob but When I try to retrieve it from server. I've encountered with difficulty which byte array from server gives in BigInteger from server. How I could get data in byte array instead of BigInteger?When I write in insert byte array this data which column is BLOB. Here is my code
Repository
public interface ArriveRepository extends JpaRepository<ArriveEntity,Long>
{
#Query(value = "select arrive.time,air_lines.image,arrive.flight,arrive.destination_uzb," +
"arrive.destination_eng,arrive.destination_rus,arrive.status,arrive.status_time " +
"from arrive inner join air_lines on air_lines.id = arrive.airline_id where arrive.arrive_date = (:date1)",nativeQuery = true)
List<Object[]> getForArriveTerminal(#Param("date1") LocalDate date1);
}
When I retrieve data from server I'm using this class
ArriveTerminalDto
public class ArriveTerminalDto {
private String time;
private BigInteger logo;
private String flight;
private String destinationUzb;
private String destinationEng;
private String destinationRus;
private String status;
private String statusTime;
//getter setter}
Service class
public List<ArriveTerminalDto> getToShow(LocalDate date1)
{
List<ArriveTerminalDto> list = new ArrayList<>();
List<Object[]> list1 = arriveRepository.getForArriveTerminal(date1);
for(Object[] objects: list1)
{
ArriveTerminalDto arriveTerminalDto = new ArriveTerminalDto();
arriveTerminalDto.setTime((String)objects[0]);
arriveTerminalDto.setLogo((BigInteger) objects[1]);
arriveTerminalDto.setFlight((String) objects[2]);
arriveTerminalDto.setDestinationUzb((String) objects[3]);
arriveTerminalDto.setDestinationRus((String) objects[4]);
arriveTerminalDto.setDestinationEng((String) objects[5]);
arriveTerminalDto.setStatus((String) objects[6]);
list.add(arriveTerminalDto);
}
return list;
}
This code works but it didn't give me byte array from server.
When I try to change BigInteger into byt[] array it gives me following errors
from postman
{
"timestamp": "2019-01-28T09:33:52.038+0000",
"status": 500,
"error": "Internal Server Error",
"message": "java.math.BigInteger cannot be cast to [B",
"path": "/arrive/terminal/date=2019-01-27"
}
Changed Object into ArriveTerminalDto but still it give error my following repo
public interface ArriveRepository extends JpaRepository<ArriveEntity,Long>
{
#Query(value = "select arrive.time,air_lines.image,arrive.flight,arrive.destination_uzb," +
"arrive.destination_eng,arrive.destination_rus,arrive.status,arrive.status_time " +
"from arrive inner join air_lines on air_lines.id = arrive.airline_id where arrive.arrive_date = (:date1)",nativeQuery = true)
List<ArriveTerminalDto> getForArriveTerminal(#Param("date1") LocalDate date1);
}
Why don't you take a look at the Spring Content community project. This project allows you to associate content with Spring Data entities. Think Spring Data but for Content, or unstructured data. This can also give you REST endpoints for the content as well, like Spring Data REST.
This approach will give you a clear abstraction for your content with implementations for many different types of storage. It is stream-based, rather than byte-based. Using byte[] won't work if you want to transfer very large files. Also getting databases to stream properly is very idiosyncratic. You probably don't want to figure all that out yourself when Spring Content already has.
This is pretty easy to add to your existing projects. I am not sure if you are using Spring Boot, or not. I'll give a non-spring boot example:
pom.xml
<!-- Java API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-jpa</artifactId>
<version>0.5.0</version>
</dependency>
<!-- REST API (if you want it) -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest</artifactId>
<version>0.5.0</version>
</dependency>
Configuration
#Configuration
#EnableJpaStores
#Import("org.springframework.content.rest.config.RestConfiguration.class")
public class ContentConfig {
// schema management
//
#Value("/org/springframework/content/jpa/schema-drop-mysql.sql")
private Resource dropContentTables;
#Value("/org/springframework/content/jpa/schema-mysql.sql")
private Resource createContentTables;
#Bean
DataSourceInitializer datasourceInitializer() {
ResourceDatabasePopulator databasePopulator =
new ResourceDatabasePopulator();
databasePopulator.addScript(dropContentTables);
databasePopulator.addScript(createContentTables);
databasePopulator.setIgnoreFailedDrops(true);
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource());
initializer.setDatabasePopulator(databasePopulator);
return initializer;
}
}
To associate content, add Spring Content annotations to your account entity.
ArriveEntity.java
#Entity
public class ArriveEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
.. existing fields...
#ContentId
private String contentId;
#ContentLength
private long contentLength = 0L;
// if you have rest endpoints
#MimeType
private String mimeType = "text/plain";
}
Create a "store":
ArrivEntityContentStore.java
#StoreRestResource(path="arriveEntityContent)
public interface ArrivEntityContentStore extends ContentStore<ArriveEntity, String> {
}
This is all you need to create REST endpoints # /arriveEntityContent. When your application starts, Spring Content will look at your dependencies (seeing Spring Content JPA/REST), look at your ArrivEntityContentStore interface and inject an implementation of that interface for JPA. It will also inject a #Controller that forwards http requests to that implementation. This saves you having to implement any of this yourself which I think is what you are after.
So...
To access content with a Java API, auto-wire ArrivEntityContentStore and use it methods.
Or to access content with a REST API:
curl -X POST /arriveEntityContent/{arriveEntityId}
with a multipart/form-data request will store the image in the database and associate it with the account entity whose id is itemId.
curl /arriveEntityContent/{arriveEntityId}
will fetch it again and so on...supports full CRUD.
There are a couple of getting started guides here. The reference guide is here. And there is a tutorial video here. The coding bit starts about 1/2 way through.
HTH
Try to change entity definition to handle byte[] directly, but suggest JPA to interpret it as Lob. You can do it with #Lob annotation:
public class ArriveTerminalDto {
private String time;
#Lob
private byte[] logo;
private String flight;
private String destinationUzb;
private String destinationEng;
private String destinationRus;
private String status;
private String statusTime;
}
Laster, as #Clijsters suggested, you can change your repo to return List<ArriveTerminalDto>.

#JsonIgnore field in frontend UI and include it in Jsonb json serialization to store in Postgres

I need a field to be ignored in front end UI, whereas the same field will be calculated in backend and needs to get stored in Postgres DB as a Jsonb object. Other than transforming the value object into a newer one, do we have any feature in Jackon for this use case.
Test.java
public class Test {
private Integer score;
private Date dateValidated = null;
private Boolean consent = false;
private Date dateConsented;
public void setConsent(Boolean consent) {
this.consent = consent;
this.dateConsented = consent ? new Date() : null;
}
}
Based on consent, dateConsented will be set and i don't want this to be set while calling my service. I can use #JsonIgnore for this
Problem
I will store this Test as json object in postgres (Jsonb). So if i use #JsonIgnore dateConsented will be ignored in DB as well. I don't want that to happen. Any suggestions/solution for this?
Just create a resource class for yourself, and convert this class to it. finally return this resource class to frontend UI.Take a look ConverterFactory from spring.

How to retrieve a list from DynamoDB?

Im having a specific error when running a scan expression on a table within my DynamoDB Database. There is one item in my Projects table as of now. This item contains a project description and a list of Strings of team mates. When retrieving the information for the project description my code prints out the correct name of the project. However when trying to retrieve the list of team mates from this same item it says that the list is a null object reference. I can not seem to understand why the list being returned is null. Assume all permissions have been set properly within the IAM console, and the database.
Below is the code for my thread which scans the table.
public void run() {
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression();
//returns a list of items from the table. each item is of Project type
List<Project> scanResult=mapper.scan(Project.class,scanExpression);
//for each project within scanResult do the following
for (Project project: scanResult){
//retrieve the name of the team (this portion of the code logs the project name properly)
String team=project.getProjectname();
Log.v("team",team.toString());
//The list being returned from this one line below is null??
List<String> teammates=project.getTeammates();
Log.v("Teammate", teammates.get(0));
}
}
};
Thread mythread = new Thread(runnable);
mythread.start();
Below is the code for the Projects Class which serves as a template when scanning the table. This is most likely the area of the issue because the project description string is being returned properly, however the List of teamMates isnt. Perhaps I am not supposed to be using a List, or the List is not defined properly, or the use of Java annotations is not done correctly on this table !!!! However I can not find the issue
package com.example.varun.finalproject;
import com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.*;
import java.util.List;
/**
* Created by Varun on 4/10/17.
*/
#DynamoDBTable(tableName = "SBUProjects")
public class Project {
private String ProjectName;
private List<String> TeamMates;
#DynamoDBHashKey(attributeName = "ProjectName")
public String getProjectname() {
return ProjectName;
}
public void setProjectname(String projectName) {
this.ProjectName = projectName;
}
public List<String> getTeammates() {
return TeamMates;
}
public void setTeammates(List teammates) {
this.TeamMates= TeamMates;
}
}
Lastly here is a photo of my table and the item that contains a String for the project description and a List of Strings for my TeamMates. I assumed because the table determined teamMates to be a list I should also create a List when returning teamMates.
http://i67.tinypic.com/2qnm58h.jpg
Help would be appreciated.
You need to set annotation above the getTeammates() method, similar to how you set it for the getProjectname() method.
For example,
#DynamoDBAttribute(attributeName = "teammates")

ConversionFailedException: Persisting a DBObject but retrieving returns a LinkedHashMap<?, ?>

I am persisting a object:
#Document
public class PotentialCandidates {
#Id
private String jobid;
#CreatedDate
private DateTime created;
#LastModifiedDate
private DateTime modified;
private DBObject potentialcandidates;
public String getJobid() {
return this.jobid;
}
public void setJobid(String jobid) {
this.jobid = jobid;
}
public DBObject getPotentialcandidates() {
return this.potentialcandidates;
}
public void setPotentialcandidates(DBObject potentialcandidates) {
this.potentialcandidates = potentialcandidates;
}
}
where potentialCandidates are set from a JSON string as so:
potentialCandidatesObj.setPotentialcandidates((DBObject)JSON.parse(valStr));
This persists fine to my mongodb and gives me an object on the DB I can drill down into, however when I try to retrieve my db object:
public PotentialCandidates getPotentialCandidatesByJobid(String jobid) throws NoSuchPotentialCandidatesException , SystemException{
PotentialCandidates Jobid = null;
try {
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(jobid));
Jobid = mongoTemplateJobs.findOne(query, PotentialCandidates.class,
COLLECTION_NAME);
return Jobid;
} catch (Exception ex) {
throw new SystemException(ex);
} finally {
if (Jobid == null) {
throw new NoSuchPotentialCandidatesException("No User with jobid: "
+ jobid + "found..");
}
}
}
I encounter the following error:
org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.util.ArrayList<?> to type com.mongodb.DBObject for value 'myString'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.util.LinkedHashMap<?, ?> to type com.mongodb.DBObject
So it would seem I need some sort of logic to handle retrieves from mongo. I could use a different return class in my findOne query but that seems a little messy. Is there a standard approach to dealing with this?
your error is probably exactly what it says in your exception: a ConversionFailed Exception caused by someone/something trying to convert from ArrayList to a LinkedHashMap; but there is just no fitting converter for that (ConverterNotFoundException).
where exactly this is happening is impossible to say since you only posted very little code. i can not find the String "myString" in your code, yet it is mentioned in the error.
Is there a standard approach to dealing with this?
spring data usually uses converters in its mapping process. to have more control over the mapping process some people prefer to implement and register a custom converter for their classes.
you can read about converters here
http://docs.spring.io/spring-data/data-mongo/docs/current/reference/html/mongo.core.html#mongo.custom-converters
and here
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html#core-convert
maybe this will already be enough for you to fix the error yourself.
Edit: a short comment about this line:
potentialCandidatesObj.setPotentialcandidates((DBObject)JSON.parse(valStr));
you are casting to DBObject before calling the setter, because the setter takes a DBObject. this is bad, you should create another setter for JSON and do the casting there, or you will end up doing that casting operation everywhere in your code; that's not very DRY.
there is also something called DBRefs in spring data:
The mapping framework doesn't have to store child objects embedded within the document. You can also store them separately and use a DBRef to refer to that document. When the object is loaded from MongoDB, those references will be eagerly resolved and you will get back a mapped object that looks the same as if it had been stored embedded within your master document.
you might prefer this over a embedded DBObject.

Separate database model from Network model

Im using GreenDAO and Volley. So I have the following problem: When I make a network request I need to parse with GSON so I have a model to represent entities retrieved from server and other model to represent the GreenDAO objects. Is there any way to only have 1 class per model to represent as a GSON and a Class of ORM?
class Product:
#SerializedName("id")
private String id;
#SerializedName("pictures")
private List<Picture> pictures;
get & set
class PersistentProduct:
private Long id;
private List<Picture> pictures;
/** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */
public List<PersistencePicture> getPictures() {
if (pictures == null) {
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
PersistencePictureDao targetDao = daoSession.getPersistencePictureDao();
List<PersistencePicture> picturesNew = targetDao._queryPersistenceProduct_Pictures(id);
synchronized (this) {
if(pictures == null) {
pictures = picturesNew;
}
}
}
return pictures;
}
First I thought to make a Interface, but when you retrieve the data from a DAO the DAO returns the class and not the interface, so I think cannot do in this way, the only solution I found is to make a "ProductUtils" that converts from a "PersistentProduct" to a "Product" and vice versa.
The most elegant way would be to implement a small extension for greendao, so that you can specify the serialized name during schema-creation.
For Example:
de.greenrobot.daogenerator.Property.java:
// in PropertyBuilder append these lines
public PropertyBuilder setSerializedName(String sname) {
// Check the sname on correctness (i.e. not empty, not containing illegal characters)
property.serializedName = sname;
return this;
}
// in Property append these lines
private String serializedName = null;
public boolean isSerialized() {
return serializedName != null;
}
In entity.ftl add this line after line 24 (after package ${entity.javaPackage};):
<#if property.serializedName??>
import com.google.gson.annotations.SerializedName;
</#if>
And after line 55 (after: <#list entity.properties as property>)
<#if property.serializedName??>
#SerializedName("${property.serializedName}")
</#if>
Afterwards you should be able to use you generated greendao-entity for volley with the following restrictions:
If you get a Product over network, nothing is changed in the db, yet. You have to call insertOrReplace().
If you get a Product from db and send it via network some undesired fields might be serialized (i.e. myDao and daoSession)
If you get a Product via network and call insertOrReplace() the "network"-Product will be persisted and a already existing Product will be replaced by it BUT the referenced entities won't get updated or persisted if insertOrReplace() isn't called for each of them!
If you get a Product via network and call insertOrReplace() for every referenced entity toMany-entities that were referenced by the db-Product are still referenced by the updated Product, although they are not listed in the updated Product. You have to call resetPictures() and getPictures() to get the correct list, which will contain all toMany()-entities references by either the original Product stored in DB or the updated Product from network.
Update addressing 2.
To prevent daoSession and myDao from being serialized, you can use the following ExclusionStrategy:
private static class TransientExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipClass(Class<?> clazz) {
return (clazz.getModifiers() & java.lang.reflect.Modifier.TRANSIENT) != 0;
}
public boolean shouldSkipField(FieldAttributes f) {
return f.hasModifier(java.lang.reflect.Modifier.TRANSIENT);
}
}
Update addressing 1.,3. and 4.
As a fast solution you can add the following method in the KEEP-SECTIONS of your entity:
public void merge(DaoSession s) {
s.insertOrReplace(this);
// do this for all toMany-relations accordingly
for (Picture p : getPictures()) {
s.insertOrReplace(p);
newPics.add(p.getId());
}
resetPictures();
}
This will result in the original entity being updated and attached to the session and dao. Also every Picture that is references by the network-product will be persisted or updated. Pictures reference by the original entity, but not by the network-entity remain untouched and get merged into the list.
This is far from perfect, but it shows where to go and what to do. The next steps would be to do everything that is done in merge() inside one transaction and then to integrate different merge-methods into dao.ftl.
NOTE
The code given in this answer is neither complete nor tested and is meant as a hint on how to solve this. As pointed out above this solution still has some restrictions, that have to be dealt with.

Categories

Resources