jsonschema2pojo with URL doesn't works - java
I have problems with using jsonschema2pojo in my code.
So, I use jsonschema2pojo generator(http://www.jsonschema2pojo.org/) to generate POJO's from this URL: http://store.steampowered.com/api/appdetails/?appids=10
Finally, I create all these class in one package 'model'.
Then in I try use it to read json from link but I receive exception:
Exception in thread "main" java.lang.NullPointerException
at controller.View.main(View.java:26)
I don't understand why.
Here is code How I can do it:
public class View {
private static String urlStr = "http://store.steampowered.com/api/appdetails/?appids=10";
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
try {
Game game = objectMapper.readValue(new URL(urlStr), Game.class);
System.out.println(game.getData().getName());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The Game.class is finall class which I set in generator as 'Class name'.
What is wrong? How can I get all these data from this link?
In maven I configure it like that:
<plugin>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>0.4.18</version>
<configuration>
<sourceType>jsonschema</sourceType>
<outputEncoding>${project.build.sourceEncoding}</outputEncoding>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<annotationStyle>jackson2</annotationStyle>
<generateBuilders>true</generateBuilders>
<initializeCollections>true</initializeCollections>
</configuration>
<executions>
<execution>
<id>generate-game</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<targetPackage>model.game</targetPackage>
<sourceDirectory>${basedir}/src/main/resources/schema/game</sourceDirectory>
</configuration>
</execution>
</executions>
</plugin>
As I said, all classes are in src/main/java and package 'model', my schema is in sr/main/resources/schema/ in file 'game'
And my schema looks like:
{
"type": "object",
"required":false,
"javaType":"model.Game",
"properties": {
"10": {
"id": "10",
"type": "object",
"properties": {
"success": {
"id": "success",
"type": "boolean"
},
"data": {
"id": "data",
"type": "object",
"properties": {
"type": {
"id": "type",
"type": "string"
},
"name": {
"id": "name",
"type": "string"
},
"steam_appid": {
"id": "steam_appid",
"type": "integer"
},
"required_age": {
"id": "required_age",
"type": "integer"
},
"is_free": {
"id": "is_free",
"type": "boolean"
},
"detailed_description": {
"id": "detailed_description",
"type": "string"
},
"about_the_game": {
"id": "about_the_game",
"type": "string"
},
"supported_languages": {
"id": "supported_languages",
"type": "string"
},
"header_image": {
"id": "header_image",
"type": "string"
},
"website": {
"id": "website",
"type": "null"
},
"pc_requirements": {
"id": "pc_requirements",
"type": "object",
"properties": {
"minimum": {
"id": "minimum",
"type": "string"
}
}
},
"mac_requirements": {
"id": "mac_requirements",
"type": "object",
"properties": {
"minimum": {
"id": "minimum",
"type": "string"
}
}
},
"linux_requirements": {
"id": "linux_requirements",
"type": "object",
"properties": {
"minimum": {
"id": "minimum",
"type": "string"
}
}
},
"developers": {
"id": "developers",
"type": "array",
"items": {
"id": "0",
"type": "string"
}
},
"publishers": {
"id": "publishers",
"type": "array",
"items": {
"id": "0",
"type": "string"
}
},
"price_overview": {
"id": "price_overview",
"type": "object",
"properties": {
"currency": {
"id": "currency",
"type": "string"
},
"initial": {
"id": "initial",
"type": "integer"
},
"final": {
"id": "final",
"type": "integer"
},
"discount_percent": {
"id": "discount_percent",
"type": "integer"
}
}
},
"packages": {
"id": "packages",
"type": "array",
"items": [
{
"id": "0",
"type": "string"
},
{
"id": "1",
"type": "integer"
},
{
"id": "2",
"type": "integer"
},
{
"id": "3",
"type": "integer"
}
]
},
"package_groups": {
"id": "package_groups",
"type": "array",
"items": {
"id": "0",
"type": "object",
"properties": {
"name": {
"id": "name",
"type": "string"
},
"title": {
"id": "title",
"type": "string"
},
"description": {
"id": "description",
"type": "string"
},
"selection_text": {
"id": "selection_text",
"type": "string"
},
"save_text": {
"id": "save_text",
"type": "string"
},
"display_type": {
"id": "display_type",
"type": "integer"
},
"is_recurring_subscription": {
"id": "is_recurring_subscription",
"type": "string"
},
"subs": {
"id": "subs",
"type": "array",
"items": [
{
"id": "0",
"type": "object",
"properties": {
"packageid": {
"id": "packageid",
"type": "string"
},
"percent_savings_text": {
"id": "percent_savings_text",
"type": "string"
},
"percent_savings": {
"id": "percent_savings",
"type": "integer"
},
"option_text": {
"id": "option_text",
"type": "string"
},
"option_description": {
"id": "option_description",
"type": "string"
},
"can_get_free_license": {
"id": "can_get_free_license",
"type": "string"
},
"is_free_license": {
"id": "is_free_license",
"type": "boolean"
},
"price_in_cents_with_discount": {
"id": "price_in_cents_with_discount",
"type": "integer"
}
}
},
{
"id": "1",
"type": "object",
"properties": {
"packageid": {
"id": "packageid",
"type": "integer"
},
"percent_savings_text": {
"id": "percent_savings_text",
"type": "string"
},
"percent_savings": {
"id": "percent_savings",
"type": "integer"
},
"option_text": {
"id": "option_text",
"type": "string"
},
"option_description": {
"id": "option_description",
"type": "string"
},
"can_get_free_license": {
"id": "can_get_free_license",
"type": "string"
},
"is_free_license": {
"id": "is_free_license",
"type": "boolean"
},
"price_in_cents_with_discount": {
"id": "price_in_cents_with_discount",
"type": "integer"
}
}
},
{
"id": "2",
"type": "object",
"properties": {
"packageid": {
"id": "packageid",
"type": "integer"
},
"percent_savings_text": {
"id": "percent_savings_text",
"type": "string"
},
"percent_savings": {
"id": "percent_savings",
"type": "integer"
},
"option_text": {
"id": "option_text",
"type": "string"
},
"option_description": {
"id": "option_description",
"type": "string"
},
"can_get_free_license": {
"id": "can_get_free_license",
"type": "string"
},
"is_free_license": {
"id": "is_free_license",
"type": "boolean"
},
"price_in_cents_with_discount": {
"id": "price_in_cents_with_discount",
"type": "integer"
}
}
},
{
"id": "3",
"type": "object",
"properties": {
"packageid": {
"id": "packageid",
"type": "integer"
},
"percent_savings_text": {
"id": "percent_savings_text",
"type": "string"
},
"percent_savings": {
"id": "percent_savings",
"type": "integer"
},
"option_text": {
"id": "option_text",
"type": "string"
},
"option_description": {
"id": "option_description",
"type": "string"
},
"can_get_free_license": {
"id": "can_get_free_license",
"type": "string"
},
"is_free_license": {
"id": "is_free_license",
"type": "boolean"
},
"price_in_cents_with_discount": {
"id": "price_in_cents_with_discount",
"type": "integer"
}
}
}
]
}
}
}
},
"platforms": {
"id": "platforms",
"type": "object",
"properties": {
"windows": {
"id": "windows",
"type": "boolean"
},
"mac": {
"id": "mac",
"type": "boolean"
},
"linux": {
"id": "linux",
"type": "boolean"
}
}
},
"metacritic": {
"id": "metacritic",
"type": "object",
"properties": {
"score": {
"id": "score",
"type": "integer"
},
"url": {
"id": "url",
"type": "string"
}
}
},
"categories": {
"id": "categories",
"type": "array",
"items": [
{
"id": "0",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"description": {
"id": "description",
"type": "string"
}
}
},
{
"id": "1",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"description": {
"id": "description",
"type": "string"
}
}
}
]
},
"genres": {
"id": "genres",
"type": "array",
"items": {
"id": "0",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "string"
},
"description": {
"id": "description",
"type": "string"
}
}
}
},
"screenshots": {
"id": "screenshots",
"type": "array",
"items": [
{
"id": "0",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "1",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "2",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "3",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "4",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "5",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "6",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "7",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "8",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "9",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "10",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "11",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
},
{
"id": "12",
"type": "object",
"properties": {
"id": {
"id": "id",
"type": "integer"
},
"path_thumbnail": {
"id": "path_thumbnail",
"type": "string"
},
"path_full": {
"id": "path_full",
"type": "string"
}
}
}
]
},
"recommendations": {
"id": "recommendations",
"type": "object",
"properties": {
"total": {
"id": "total",
"type": "integer"
}
}
},
"achievements": {
"id": "achievements",
"type": "object",
"properties": {
"total": {
"id": "total",
"type": "integer"
}
}
},
"release_date": {
"id": "release_date",
"type": "object",
"properties": {
"coming_soon": {
"id": "coming_soon",
"type": "boolean"
},
"date": {
"id": "date",
"type": "string"
}
}
},
"support_info": {
"id": "support_info",
"type": "object",
"properties": {
"url": {
"id": "url",
"type": "string"
},
"email": {
"id": "email",
"type": "string"
}
}
},
"background": {
"id": "background",
"type": "string"
}
}
}
},
"required": [
"success",
"data",
"id",
"path_thumbnail",
"path_full"
]
}
},
"required": [
"10"
]
}
With this config I can read all data using this line instead of before System.out.println:
System.out.println( objectMapper.writeValueAsString( game ) );
Now I can see full json string, but how can I read it using 'game.getData().getName()' etc ?
The JSON schema that you gave defines "10" as a top-level property containing everything else.
{
"type": "object",
"required":false,
"javaType":"model.Game",
"properties": {
"10": {
"id": "10",
"type": "object",
"properties": {
"success": {
"id": "success",
"type": "boolean"
},
"data": {
"id": "data",
"type": "object",
"properties": {
"type": {
"id": "type",
"type": "string"
},
"name": {
"id": "name",
"type": "string"
},
...
jsonschema2pojo reads that schema and generates a class named _10 as part of the model. You can find this in _10.java in the generated-sources directory.
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({
"success",
"data"
})
public class _10 {
I don't know if this was intentional in the schema. If it's intentional, then you would need to access the name like this.
System.out.println(game.get10().getData().getName());
I was able to get it working after making that change.
EDIT: It appears these JSON messages are expected to have a variable ID as a top-level key containing everything else, so we need to handle this a bit differently. We can generalize the schema so that it isn't specific to a particular ID, and then we can use a two-step process to parse the message. First, we'll use [ObjectMapper#readValue](https://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/ObjectMapper.html#readValue(java.net.URL, com.fasterxml.jackson.core.type.TypeReference)) to parse the whole message into a Map<String, Object>. We expect that top-level map will contain a single element, corresponding to the ID of the document we requested, and its value will be a sub-map containing the values we're interested in. We'll then pass that sub-map through [ObjectMapper#convertValue](https://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/ObjectMapper.html#convertValue(java.lang.Object, java.lang.Class)) to get the Game object that we want.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cnauroth</groupId>
<artifactId>test-json</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>Test JSON</name>
<description>Test JSON</description>
<build>
<plugins>
<plugin>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>0.4.18</version>
<configuration>
<sourceType>jsonschema</sourceType>
<outputEncoding>${project.build.sourceEncoding}</outputEncoding>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
<annotationStyle>jackson2</annotationStyle>
<generateBuilders>true</generateBuilders>
<initializeCollections>true</initializeCollections>
</configuration>
<executions>
<execution>
<id>generate-game</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<targetPackage>model.game</targetPackage>
<sourceDirectory>${basedir}/src/main/resources/schema/game</sourceDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<mainClass>View</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>${project.artifactId}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
game
The JSON schema file is too large to paste, so here is a link to a gist.
View.java
import java.net.URI;
import java.util.Map;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import model.Game;
public class View {
public static void main(String[] args) throws Exception {
String id = args[0];
URI uri = new URI("http", "store.steampowered.com", "/api/appdetails",
"appids=" + id, null);
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> obj = objectMapper.readValue(uri.toURL(),
new TypeReference<Map<String, Object>>(){});
Game game = objectMapper.convertValue(obj.get(id), Game.class);
System.out.println(game.getData().getName());
}
}
Demo
> mvn clean package
> java -jar target/test-json.jar 10
Counter-Strike
> java -jar target/test-json.jar 219
Half-Life 2: Demo
Additionally, I needed to make one other change to the schema. I removed the linux_requirements property. This is because looking at document 10 vs. document 219, it's an object in the former and it's an array in the latter. For document 219, the parser didn't know how to make sense of the array, because we were expecting an object. It's odd for data returned from an API to be inconsistent like this. You might need to do some more tinkering with the schema to get this fully working for all possible JSON documents returned from that API.
I have put all of the code into a GitHub repository. You can take that code, build it and run it to see it working. Then, you can adapt it further to your needs.
Instead of trying to model the object containing the ids with properties, use additionalProperties. Assuming that the top level type contains several games, you could try replacing
{
"type": "object",
"required":false,
"javaType":"model.Game",
"properties": {
"10": {
"id": "10",
"type": "object",
...
}
}
}
with something like
{
"type": "object",
"required":false,
"javaType":"model.Games",
"additionalProperties": {
"id": "game",
"type": "object",
"javaType": "model.Game"
...
}
}
This should make a model.Games type with a method like public Map<String, Game> getAdditionalProperties().
Related
Build JSON from a very complex JSON Schema in Java
I have a complex issue here and some advice or suggestions would be greatly appreciated. Essentially I have a complex JSON schema that looks something like this: { "$schema": "http://example.org", "$id": "http://example.org", "title": "schema title", "description": "description", "properties": { "name": { "description": "description", "type": "string", "enum": [ "name1", "name2" ] }, "storage": { "description": "description", "type": "integer", "minimum": "200", "maximum": "500", "default": "200", }, "domain": { "description": "description", "type": "string" }, }, "if": { "properties": { "name": { "const": "name1" } } }, "then": { "if": { "properties": { "version": { "const": "version1" } } }, "then": { "properties": { "cpus": { "description": "description", "type": "integer", "minimum": 1, "maximum": 8 }, "memory": { "description": "description", "type": "integer", "minimum": 1, "maximum": 32 }, }, "required": [ "cpus", "memory" ] }, "else": { "if": { "properties": { "version": { "const": "version2" } } }, "then": { "properties": { "cpus": { "description": "description", "type": "integer", "minimum": 1, "maximum": 8 }, "diskSize": { "description": "description", "type": "integer", "minimum": 250, "maximum": 1000 }, }, "required": [ "cpus", "diskSize" ] } } }, "else": { "if": { "properties": { "name": { "const": "name2" } } }, "then": { "if": { "properties": { "version": { "const": "version3" } } }, "then": { "properties": { "diskSize": { "description": "description", "type": "integer", "minimum": 100, "maximum": 500 } "memory": { "description": "description", "type": "integer", "minimum": 1, "maximum": 28 } }, "required": [ "diskSize", "memory" ] }, "else": { "if": { "properties": { "version": { "const": "version4" } } }, "then": { "properties": { "cpus": { "description": "description", "type": "integer", "minimum": 1, "maximum": 28 }, "memory": { "description": "description", "type": "integer", "minimum": 1, "maximum": 64 } }, "required": [ "cpus", "memory" ] } } } } } I need to build a JSON object using this schema in java. Every property in the schema is inside of a map that I have access to, so I can quite simply just get the property from the map and add it to a JsonNode object that I am building. Every property under the initial "properties" object is easy to retrieve, I can just get a list of them and then get each one from the map. The complexity lies in the if/then/else part of the json schema. The only way I can see to find which property I need is to first build the initial part of the json from the first "properties" object and then have some sort of quite complex recursive algorithm that goes into every if/then/else statement and compares the value of the property being evaluated and then returns a list of the properties I need to get from the map. I have looked around online for a library that can build Json from a Json schema in java but haven't found anything that can deal with the complex if/then/else statements. Any suggestions or ideas would be greatly appreciated.
will spring-data-rest expose methods in QueryByExampleExecutor interface?
i just learned how to use spring-data-rest to expose methods in repository. i wonder will the spring-data-rest expose methods in QueryByExampleExecutor<T>interface.if not, is there anyway to expose those methods. thx :). i have a repository class that extend JpaRepository and i did not find any Restful api like methods in QueryByExampleExecutor<T> with resource discovery api. this is what i got from resource discovery api { "alps": { "version": "1.0", "descriptor": [ { "id": "studentEntity-representation", "href": "http://127.0.0.1:8080/data/profile/studentEntities", "descriptor": [ { "name": "name", "type": "SEMANTIC" }, { "name": "age", "type": "SEMANTIC" }, { "name": "height", "type": "SEMANTIC" }, { "name": "weight", "type": "SEMANTIC" }, { "name": "hasPassed", "type": "SEMANTIC" } ] }, { "id": "create-studentEntities", "name": "studentEntities", "type": "UNSAFE", "descriptor": [], "rt": "#studentEntity-representation" }, { "id": "get-studentEntities", "name": "studentEntities", "type": "SAFE", "descriptor": [ { "name": "page", "type": "SEMANTIC", "doc": { "format": "TEXT", "value": "The page to return." } }, { "name": "size", "type": "SEMANTIC", "doc": { "format": "TEXT", "value": "The size of the page to return." } }, { "name": "sort", "type": "SEMANTIC", "doc": { "format": "TEXT", "value": "The sorting criteria to use to calculate the content of the page." } } ], "rt": "#studentEntity-representation" }, { "id": "delete-studentEntity", "name": "studentEntity", "type": "IDEMPOTENT", "descriptor": [], "rt": "#studentEntity-representation" }, { "id": "update-studentEntity", "name": "studentEntity", "type": "IDEMPOTENT", "descriptor": [], "rt": "#studentEntity-representation" }, { "id": "get-studentEntity", "name": "studentEntity", "type": "SAFE", "descriptor": [], "rt": "#studentEntity-representation" }, { "id": "patch-studentEntity", "name": "studentEntity", "type": "UNSAFE", "descriptor": [], "rt": "#studentEntity-representation" } ] } }
Highly nested json data
I have three JSON arrays named item, topping and batter. Now I want to store this data into single json object. It is highly nested data I don't know how to store data into single object like this. Resultant object should be like this: { "item": [{ "id": "0001", "type": "donut", "name": "Cake", "ppu": 0.55, "batter": [{ "id": "1001", "type": "Regular" }, { "id": "1002", "type": "Chocolate" }, { "id": "1003", "type": "Blueberry" }, { "id": "1004", "type": "Devil's Food" } ], "topping": [{ "id": "5001", "type": "None" }, { "id": "5002", "type": "Glazed" }, { "id": "5005", "type": "Sugar" }, { "id": "5007", "type": "Powdered Sugar" }, { "id": "5006", "type": "Chocolate with Sprinkles" }, { "id": "5003", "type": "Chocolate" }, { "id": "5004", "type": "Maple" } ] }, { "id": "0002", "type": "donut", "name": "Raised", "ppu": 0.55, "batter": [{ "id": "1001", "type": "Regular" }], "topping": [{ "id": "5001", "type": "None" }, { "id": "5002", "type": "Glazed" }, { "id": "5005", "type": "Sugar" }, { "id": "5003", "type": "Chocolate" }, { "id": "5004", "type": "Maple" } ] }, { "id": "0003", "type": "donut", "name": "Old Fashioned", "ppu": 0.55, "batter": [{ "id": "1001", "type": "Regular" }, { "id": "1002", "type": "Chocolate" } ], "topping": [{ "id": "5001", "type": "None" }, { "id": "5002", "type": "Glazed" }, { "id": "5003", "type": "Chocolate" }, { "id": "5004", "type": "Maple" } ] } ] }
Elasticsearch:Getting nested object under path is not of nested type
I am new to the Elastic search world.Basically I am trying to retrieve the nested objects based on the ID.This is the JSON representation of my document. { "_index": "xyz", "_type": "abc", "_id": "12", "_version": 1, "found": true, "_source": { "lastModifiedBy": "12", "lastModifiedDate": "2015-12-31T19:45:29.493Z", "profile": [ { "type": "nested", "views": [ { "type": "nested", "id": "view1", "name": "view1", "properties": [ { "name": "default", "value": false } ], "widgets": [ { "type": "nested", "id": "graph", "name": "graph", "elementId": "ui_graph", "properties": [ { "name": "currency", "value": "YEN" } ] } ] } } ] } ] I am trying to get the widgets based on the view id.This is the my search query. "query" : { "term" : { "_id" : "12" } }, "post_filter" : { "nested" : { "query" : { "filtered" : { "query" : { "match_all" : { } }, "filter" : { "term" : { "profile.views.id" : "view1" } } } }, "path" : "profile.views" } } } I am not sure what is wrong here.But getting "nested object under path [profile.views] is not of nested type]". Below is my mapping structure { "xyz": { "mappings": { "abc": { "properties": { "lastModifiedBy": { "type": "string" }, "lastModifiedDate": { "type": "date", "format": "dateOptionalTime" }, "name": { "type": "string" }, "profile": { "properties": { "lastModifiedBy": { "type": "string" }, "lastModifiedDate": { "type": "date", "format": "dateOptionalTime" }, "type": { "type": "string" }, "views": { "properties": { "id": { "type": "string" }, "isDefault": { "type": "boolean" }, "name": { "type": "string" }, "properties": { "properties": { "name": { "type": "string" }, "type": { "type": "string" }, "value": { "type": "string" } } }, "type": { "type": "string" }, "viewId": { "type": "string" }, "widgets": { "properties": { "elementId": { "type": "string" }, "id": { "type": "string" }, "name": { "type": "string" }, "properties": { "properties": { "name": { "type": "string" }, "type": { "type": "string" }, "value": { "type": "string" } } }, "type": { "type": "string" } } } } } } } } } } } } Please help!
You are getting the error because you have not specified type as nested for profile and views. Refer to the Docs for how to created nested objects . You should be defining type as nested for every nested object like this { "xyz": { "mappings": { "abc": { "properties": { "lastModifiedBy": { "type": "string" }, "lastModifiedDate": { "type": "date", "format": "dateOptionalTime" }, "name": { "type": "string" }, "profile": { "type": "nested", <--- here, you need this for every nested object "properties": { "lastModifiedBy": { "type": "string" }, "lastModifiedDate": { "type": "date", "format": "dateOptionalTime" }, "type": { "type": "string" }, "views": { "type": "nested", "properties": { "id": { "type": "string" }, "isDefault": { "type": "boolean" }, "name": { "type": "string" }, "properties": { "type": "nested", "properties": { "name": { "type": "string" }, "type": { "type": "string" }, "value": { "type": "string" } } }, "type": { "type": "string" }, "viewId": { "type": "string" }, "widgets": { "type": "nested", "properties": { "elementId": { "type": "string" }, "id": { "type": "string" }, "name": { "type": "string" }, "properties": { "type": "nested", "properties": { "name": { "type": "string" }, "type": { "type": "string" }, "value": { "type": "string" } } }, "type": { "type": "string" } } } } } } } } } } } } Hope this helps!!
jsonschema2pojo: referencing objects of the same type
I need to generate Java classes from a JSON schema file and came across jsonschema2pojo. However, I encountered a "problem" when using the ref keyword. For example, if I use the following schema from http://spacetelescope.github.io/understanding-json-schema/structuring.html#extending: { "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "address": { "type": "object", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" } }, "required": ["street_address", "city", "state"] } }, "type": "object", "properties": { "billing_address": { "$ref": "#/definitions/address" }, "shipping_address": { "$ref": "#/definitions/address" } } } As expected, it generated a class named whatever you want to call it, containing an attribute billingAddress and an attribute shippingAddress. However, it also generated two separate classes BillingAddress and ShippingAddress even though both attributes are referencing to address. Hence, I would rather have both attributes of type Address. Is this possible to achieve with jsonschema2pojo?
Update After getting a better understanding of javaType from here. I get the expected result by just adding a javaType in your Address definition. { "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "address": { "type": "object", "javaType": "Address", "properties": { "street_address": { "type": "string" }, "city": { "type": "string" }, "state": { "type": "string" } }, "required": ["street_address", "city", "state"] } }, "type": "object", "properties": { "billing_address": { "$ref": "#/definitions/address" }, "shipping_address": { "$ref": "#/definitions/address" } } } Answer with two files You need to use javaType in your Address.json and use $ref for your billing_address and shipping address. I would suggest you to separate the address definition into a separate json and then use that in your billing_address and shipping_address. Address.json { "$schema": "http://json-schema.org/draft-03/hyper-schema", "additionalProperties": false, "javaType": "whatever-package-name-you-have.Address" "type": "object", "properties": { "street_address": { "type": "string", "required":true}, "city": { "type": "string", "required":true }, "state": { "type": "string", "required":true } } } MainClass.json { "$schema": "http://json-schema.org/draft-03/hyper-schema", "additionalProperties": false, "type": "object", "properties": { "billing_address": { "$ref":"Address.json", "type": "object", "required": false }, "shipping_address": { "$ref":"Address.json", "type": "object", "required": false } } }