JSON unmarshalling to POJO and inserting - json

I would like to unmarshal a json string to a pojo class.
I am reading it from an existing url:
https://builds.apache.org/job/Accumulo-1.5/api/json
I am using apache camel to unmarshal the url
#Component
public class RouteBuilder extends SpringRouteBuilder {
private Logger logger = LoggerFactory.getLogger(RouteBuilder.class);
#Override
public void configure() throws Exception {
logger.info("Configuring route");
//Properties die hij niet vindt in de klasse negeren
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DataFormat reportFormat = new JacksonDataFormat(objectMapper, HealthReport.class);
from("timer://foo?fixedRate=true&delay=0&period=2000&repeatCount=1")
.routeId("accumoloToJsonRoute")
.setHeader(Exchange.HTTP_METHOD, constant("GET"))
.to("https://builds.apache.org:443/job/Accumulo-1.5/api/json")
.convertBodyTo(String.class)
.unmarshal(reportFormat) //instance van Build
.log(LoggingLevel.DEBUG, "be.kdg.teamf", "Project: ${body}")
.to("hibernate:be.kdg.teamf.model.HealthReport");
}
}
So far so good. I would like to only insert the 'healthReport' node using hibernate annotations.
#XmlRootElement(name = "healthReport")
#JsonRootName(value = "healthReport")
#Entity(name = "healthreport")
public class HealthReport implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int Id;
#Column
#JsonProperty("description")
private String description;
#Column
#JsonProperty("iconUrl")
private String iconUrl;
#Column
#JsonProperty("score")
private int score;
public HealthReport() {
}
public HealthReport(int score, String iconUrl, String description) {
this.score = score;
this.iconUrl = iconUrl;
this.description = description;
}
public String getDescription() {
return description;
}
public String getIconUrl() {
return iconUrl;
}
public int getId() {
return Id;
}
public int getScore() {
return score;
}
public void setDescription(String description) {
this.description = description;
}
public void setIconUrl(String iconUrl) {
this.iconUrl = iconUrl;
}
public void setId(int id) {
Id = id;
}
public void setScore(int score) {
this.score = score;
}
}
This is where the problem is. It does not recognize the annotations
and only null values are inserted in my database
#XmlRootElement(name = "healthReport")
#JsonRootName(value = "healthReport")
Does anybody know how to fix this?
Thanks

Fixed it using a Processor for my Route
public class HealthReportProcessor implements Processor {
#Autowired
private ConfigurationService configurationService;
#Override
public void process(Exchange exchange) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(exchange.getIn().getBody().toString());
ArrayNode report = (ArrayNode) root.get("healthReport");
int configId = configurationService.findJenkinsConfigurationByName(root.get("displayName").asText()).getId();
for (JsonNode node : report) {
JsonObject obj = new JsonObject();
obj.addProperty("description", node.get("description").asText());
obj.addProperty("iconUrl", node.get("iconUrl").asText());
obj.addProperty("score", node.get("score").asInt());
obj.addProperty("jenkinsConfig", configId);
exchange.getIn().setBody(obj.toString());
}
}
}
It is working but I think there is a better solution.
If you have a better solution please let me know ;)

Can you try this,
from("timer://foo?fixedRate=true&delay=0&period=2000&repeatCount=1")
.routeId("accumoloToJsonRoute")
.setHeader(Exchange.HTTP_METHOD,constant("GET"))
.to("https://builds.apache.org:443/job/Accumulo-1.5/apijson")
.unmarshal().json(JsonLibrary.Jackson, HealthReport.class)
And make sure the response params match the POJO fields.
Let me know if it works.

Related

SpringBoot JSON not deserializing into my request model

I am using SpringBoot and trying to deserialize JSON like:
{
"userId": "Dave",
"queryResults": {
"id": "ABC",
"carData": {.....},
"carId": "Honda",
"status": 0,
"model": "X"
}
}
, into MyRequestModel clas:
public class MyRequestModel {
private String userId;
private String: queryResults;
}
, that is received as #RequestBody parameter in my #PostMapping method that looks like:
#PostMapping
public String postDate(#RequestBody MyRequestModel data) {
...
return "posted";
}
The above queryResults field is supposed to be stored as a CLOB in a database.
Problem I am having is that if I send this JSON to hit my endpoint (PostMapping) method, it cannot deserialize it into MyRequestModel and I get this error:
Cannot deserialize instance of java.lang.String out of START_OBJECT token
at [Source: (PushbackInputStream); line: 3, column: 18] (through reference chain: MyRequestModel["queryResults"])]
I guess the real answer to your question is: if you NEED the queryResults property to be a String, then implement a custom deserializer.
If not, then, use one of the alternatives that Jonatan and Montaser proposed in the other answers.
Implementing a custom deserializer within Spring Boot is fairly straightforward, since Jackson is its default serializer / deserializer and it provides a easy way to write our own deserializer.
First, create a class that implements the StdDeserializer<T>:
MyRequestModelDeserializer.java
public class MyRequestModelDeserializer extends StdDeserializer<MyRequestModel> {
public MyRequestModelDeserializer() {
this(null);
}
public MyRequestModelDeserializer(Class<?> vc) {
super(vc);
}
#Override
public MyRequestModel deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = p.getCodec().readTree(p);
String userId = node.get("userId").asText();
String queryResults = node.get("queryResults").toString();
MyRequestModel model = new MyRequestModel();
model.setQueryResults(queryResults);
model.setUserId(userId);
return model;
}
}
Second, mark your class to be deserialized using your custom deserializer by using the #JsonDeserialize annotation:
MyRequestModel.java
#JsonDeserialize(using = MyRequestModelDeserializer.class)
public class MyRequestModel {
private String userId;
private String queryResults;
}
It's done.
queryResults is a String on Java side but it is an Object on JSON side.
You will be able to deserialize it if you send it in as a String:
{
"userId": "Dave",
"queryResults": "foo"
}
or if you create classes that maps to the fields:
public class MyRequestModel {
private String userId;
private QueryResults queryResults;
}
public class QueryResults {
private String id;
private CarData carData;
private String carId;
private Integer status;
private String model;
}
or if you serialize it into something generic (not recommended):
public class MyRequestModel {
private String userId;
private Object queryResults;
}
public class MyRequestModel {
private String userId;
private Map<String, Object> queryResults;
}
public class MyRequestModel {
private String userId;
private JsonNode queryResults;
}
You have two options to deserialize this request:-
change the type of queryResults to Map<String, Object>, it will accepts everything as an object of key and value. (Not recommended)
public class MyRequestModel {
private String userId;
private Map<String, Object> queryResults;
}
You have to create a class that wraps the results of queryResults as an object.
class QueryResult {
private String id;
private Map<String, Object> carData;
private String carId;
private Integer status;
private String model;
public QueryResult() {}
public QueryResult(String id, Map<String, Object> carData, String carId, Integer status, String model) {
this.id = id;
this.carData = carData;
this.carId = carId;
this.status = status;
this.model = model;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Map<String, Object> getCarData() {
return carData;
}
public void setCarData(Map<String, Object> carData) {
this.carData = carData;
}
public String getCarId() {
return carId;
}
public void setCarId(String carId) {
this.carId = carId;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
and make the type of queryResult as shown:-
public class MyRequestModel {
private String userId;
private QueryResult queryResults;
}

Evaluate expression json result In debug mode is different with final json result

I have a controller like this:
#ResponseBody
#RequestMapping(value = "/getLayersOfCategory/{categoryId}", method = RequestMethod.GET)
public LayersResult GetLayersOfCategory(#PathVariable("categoryId") Integer categoryId,#RequestHeader("secret") String secret) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm");
DataServicesModel dataServicesModel=new DataServicesModel();
LocalDateTime now = LocalDateTime.now();
CategoriesEntity categoriesEntity=new CategoriesEntity();
categoriesEntity.setId(categoryId);
List<Object[]> layersCategoriesEntityList=layersCategoriesRepository.findAllByCategoryId(categoryId);
List<String> stringList=new ArrayList<>();
for (Object[] row:layersCategoriesEntityList){
stringList.add(row[2].toString());
}
LayersResult layersResult=this.GetPoints(stringList);
**** return layersResult;
}
at **** when I Evaluate "layersResult" expression it shows a json like this:
but when I call the controller by postman
I get something like this:
as you see the iconUrl key has different. I do not know wher the result change at the end of the controller without any line of code tha could change the final result.
thanks in advance for replying.
And this a DataLayerModel:
package org.rajman.lbs.neshan.business.data.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParseException;
import jdk.nashorn.internal.ir.annotations.Ignore;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import javax.persistence.*;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class DataLayerModel {
private Integer id;
private String title;
private String type;
private String iconUrl="kdjjfhskdjfh";
private String webUrl="http://map.tabr*.ir";
#JsonIgnore
public String getStyle() { return style;
}
public void setStyle(String style) {
this.style = style;
}
private String style="{\"icon\":\"dt.png\"}";
#Value("${url.webUrl:#{null}}")
#JsonIgnore
public String getWebUrl() {
return webUrl;
}
public void setWebUrl(String webUrl) {
this.webUrl = webUrl;
}
public DataLayerModel() {
}
public DataLayerModel(Integer id, String title, String type, String style) {
this.id = id;
this.title = title;
this.type = type.equals("ST_Polygon") || type.equals("polygon") ? "polygon" : "point";
this.style=style;
//this.iconUrl = getIconUrl();
}
public String getIconUrl() {
Object icon;
String url="";
JSONObject jsonObject;
try {
url=this.style;
jsonObject = new JSONObject(this.style);
icon=jsonObject.get("icon");
url=this.getWebUrl()+"/images/"+icon.toString();
}
catch (Exception e){
System.out.println(e);
}
return url;
}
public void setIconUrl(String iconUrl) {
this.iconUrl = iconUrl;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Assuming iconUrl is a String. i.e. serialization is straight forward.
The only thing, I can guess that would go wrong is getIconUrl() method.
Please try to evaluate, layers.get(0).getIconUrl() at the same debug point.

Save Raw JSON as string in the database

How can I save Raw Json as String in the MsSql db with the POST request - using Jackson ObjectMapper to convert the string to Json but not able to change raw json into string?
{
"id": 1,
"someName":"someName",
"json": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossTerm": "Standard Generalized Markup Language"
}
},
"anotherjson":{
"name":"someone",
"age": 121
},
"somedate":"03-11-2019.00:00:00"
}
How can I save this save json as integer, varchar, string, string, date column in the db?
1,someName, "{"title": "example glossary","GlossDiv": {"title": "S","GlossTerm": "Standard Generalized Markup Language"}","{"name":"someone","age": 121}", 03-11-2019.00:00:00.
** Update **
For simplicity here is the simple json
{
"id":1,
"jsonObjectHolder":{
"name": "Name",
"age" : 404
}}
Controller:
#PostMapping("/postJson")
public void postJson(#RequestBody TryJson tryJson) {
tryJsonService.postJson(tryJson);
}
Service:
public void postJson(TryJson tryJson) {
tryJsonRepository.save(tryJson);
}
Repo:
public interface TryJsonRepository extends CrudRepository<TryJson, Integer> {
}
Model:
#Entity
#Table(name = "TryJson")
public class TryJson {
#Id
#Column(name = "id")
private Integer id;
#JsonIgnore
#Column(name = "json_column")
private String jsonColumn;
#Transient
private JsonNode jsonObjectHolder;
public TryJson() {
}
public TryJson(Integer id, String jsonColumn) {
this.id = id;
this.jsonColumn = jsonColumn;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public JsonNode getJsonObjectHolder() {
return jsonObjectHolder;
}
public void setJsonObjectHolder(JsonNode jsonObjectHolder) {
this.jsonObjectHolder = jsonObjectHolder;
}
public String getJsonColumn() {
return this.jsonObjectHolder.toString();
}
public void setJsonColumn(String jsonColumn) throws IOException {
ObjectMapper mapper = new ObjectMapper();
this.jsonObjectHolder = mapper.readTree(jsonColumn);
}
#Override
public String toString() {
return String.format("TryJson [Id=%s, JsonColumn=%s, jsonObjectHolder=%s]", id, jsonColumn, jsonObjectHolder);
}
}
http://localhost:8080/api/postJson
ID JSON_COLUMN
1 null
Not sure what I am missing here. I do get jsonObjectHolder populated during the debugging but then still I get NULL
TryJson [Id=1, JsonColumn=null, jsonObjectHolder={"name":"Name","age":404}]
Update 2
I am getting null pointer exception.
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: Exception occurred inside getter of com.example.tryjson.tryjson.model.TryJson.jsonColumn; nested exception is org.hibernate.PropertyAccessException: Exception occurred inside getter of com.example.tryjson.tryjson.model.TryJson.jsonColumn] with root cause
java.lang.NullPointerException: null
at com.example.tryjson.tryjson.model.TryJson.getJsonColumn(TryJson.java:52) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_192]
Here is my new model
#Entity
#Table(name = "TryJson")
public class TryJson {
private Integer id;
#Transient
private JsonNode jsonObjectHolder;
public TryJson() {
}
public TryJson(Integer id, JsonNode jsonObjectHolder) {
this.id = id;
this.jsonObjectHolder = jsonObjectHolder;
}
#Id
#Column(name = "id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Transient
public JsonNode getJsonObjectHolder() {
return jsonObjectHolder;
}
public void setJsonObjectHolder(JsonNode jsonObjectHolder) {
this.jsonObjectHolder = jsonObjectHolder;
}
#Column(name = "json_column")
public String getJsonColumn() {
return this.jsonObjectHolder.toString();
}
public void setJsonColumn(String jsonColumn) throws IOException {
ObjectMapper mapper = new ObjectMapper();
this.jsonObjectHolder = mapper.readTree(jsonColumn);
}
}
You could define a JsonNode json property to hold the part you want to persist as text, then mark it as #Transient so JPA does not try to store it on database. However, jackson should be able to translate it back and forward to Json.
Then you can code getter/setter for JPA, so you translate from JsonNode to String back and forward. You define a getter getJsonString that translate JsonNode json to String. That one can be mapped to a table column, like 'json_string', then you define a setter where you receive the String from JPA and parse it to JsonNode that will be avaialable for jackson.
Do not forget to add #JsonIgnore to getJsonString so Jackson does not try to translate to json as jsonString.
#Entity
#Table(name = "request")
public class Request {
private Long id;
private String someName;
#Transient
private JsonNode json;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
#Column(name ="someName")
public String getSomeName() {
return name;
}
public void setSomeName(String name) {
this.name = name;
}
public void setId(Long id) {
this.id = id;
}
// Getter and setter for name
#Transient // This is for Jackson
public JsonNode getJson() {
return json;
}
public void setJson(JsonNode json) {
this.json = json;
}
#Column(name ="jsonString")
public String getJsonString() { // This is for JPA
return this.json.toString();
}
public void setJsonString(String jsonString) { // This is for JPA
// parse from String to JsonNode object
ObjectMapper mapper = new ObjectMapper();
try {
this.json = mapper.readTree(jsonString);
} catch (Exception e) {
e.printStackTrace();
}
}
}
UPDATE:
If you mark jsonColumn with #Column spring will use reflection to pull out the data with default initialization null, getJsonColumn translation will never be executed:
#JsonIgnore
#Column(name = "json_column")
private String jsonColumn;
You do not need a jsonColumn, just make sure you mark your setters with #Column, so spring uses gettets/setters to persist to database, when persisting, jpa will execute getJsonColumn, when reading, jpa will execute setJsonColumn and jsonNode will be translated back and forward to string:
#Entity
#Table(name = "TryJson") public class TryJson {
private Integer id;
#Transient
private JsonNode jsonObjectHolder;
public TryJson() {
}
public TryJson(Integer id, String jsonColumn) {
this.id = id;
this.jsonObjectHolder = // use mapper to create the jsonObject;
}
#Id
#Column(name = "id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public JsonNode getJsonObjectHolder() {
return jsonObjectHolder;
}
public void setJsonObjectHolder(JsonNode jsonObjectHolder) {
this.jsonObjectHolder = jsonObjectHolder;
}
#Column(name = "json_column")
public String getJsonColumn() {
return this.jsonObjectHolder.toString();
}
public void setJsonColumn(String jsonColumn) throws IOException {
ObjectMapper mapper = new ObjectMapper();
this.jsonObjectHolder = mapper.readTree(jsonColumn);
}
#Override
public String toString() {
return String.format("TryJson [Id=%s, JsonColumn=%s, jsonObjectHolder=%s]", id, jsonColumn, jsonObjectHolder);
}
}
ObjectMapper mapper = new ObjectMapper();
TypeReference<List<User>> typeReference = new TypeReference<List<Your_Entity>>() {};
InputStream inputStream = TypeReference.class.getResourceAsStream("/bootstrap.json");
try {
List<Your_Entity> users = mapper.readValue(inputStream, typeReference);
log.info("Saving users...");
userService.saveAllUsers(users);
log.info(users.size() + " Users Saved...");
} catch (IOException e) {
log.error("Unable to save users: " + e.getMessage());
}

Dropwizard Hibernate Configuration

I am new to Dropwizard and so far everything was going well till I started messing with Hibernate and MySQL. My problem is: Hibernate won't create tables and consequently no columns in my DB.
The only warning I get when running my jar file is:
org.hibernate.cfg.environment hibernate.properties not found
But do I need it at all? As I am having all configuration and mapping already.
Here is my application class:
public class LibraryApplication extends Application<LibraryConfiguration> {
public static void main(String[] args) throws Exception {
new LibraryApplication().run(args);
}
#Override
public String getName() {
return "hello backend";
}
private final HibernateBundle<LibraryConfiguration> hibernate = new HibernateBundle<LibraryConfiguration>(Book.class){ //more entities can be added separated with a coma
public DataSourceFactory getDataSourceFactory(LibraryConfiguration configuration) {
return configuration.getDataSourceFactory();
}
};
#Override
public void initialize(Bootstrap<LibraryConfiguration> bootstrap) {
bootstrap.addBundle(new AssetsBundle("/webapp", "/", "index.html", "static"));
bootstrap.addBundle(hibernate);
}
#Override
public void run(LibraryConfiguration configuration,
Environment environment) {
final BookDAO dao = new BookDAO(hibernate.getSessionFactory());
final TestResource resource = new TestResource(
configuration.getTemplate(), configuration.getDefaultName());
final TemplateHealthCheck healthCheck = new TemplateHealthCheck(
configuration.getTemplate());
environment.healthChecks().register("template", healthCheck); //register the health check
environment.jersey().register(resource); //register the resource class
environment.jersey().register(new BookResource(dao));
}
}
YAML file:
server:
type: simple
rootPath: '/api/*'
applicationContextPath: /
connector:
type: http
port: 8080
template: Hello, %s!
defaultName: back-end
database:
# the name of your JDBC driver
driverClass: com.mysql.jdbc.Driver
# the JDBC URL
url: jdbc:mysql://localhost:3306/books
# the username
user: root
# the password
password: root
# any properties specific to your JDBC driver:
properties:
charSet: UTF-8
hibernate.dialect: org.hibernate.dialect.MySQLDialect #org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.hbm2ddl.auto: create
Configurtion class:
public class LibraryConfiguration extends Configuration{
#Valid
#NotNull
#JsonProperty
private DataSourceFactory database = new DataSourceFactory();
#JsonProperty("database")
public DataSourceFactory getDataSourceFactory() {
return database;
}
#NotEmpty
private String template;
#NotEmpty
private String defaultName = "";
#JsonProperty
public String getTemplate() {
return template;
}
#JsonProperty
public void setTemplate(String template) {
this.template = template;
}
#JsonProperty
public String getDefaultName() {
return defaultName;
}
#JsonProperty
public void setDefaultName(String name) {
this.defaultName = name;
}
}
and my entity:
#Entity
#Table(name = "book")
#NamedQueries({
#NamedQuery(
name = "library.core.Book.findAll",
query = "SELECT b FROM book b"
)
})
public class Book{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private Long id;
#Column(name = "title")
#NotNull
private String title;
#Column(name = "author")
#NotNull
private String author;
#Column(name = "date")
private long date;
#Column(name = "description")
private String description;
#Column(name = "image")
private String image;
public Book(String title, String author){
this.title = title;
this.author = author;
}
#JsonProperty
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#JsonProperty
public Long getId() {
return id;
}
#JsonProperty
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
#JsonProperty
public long getDate() {
return date;
}
public void setDate(long date) {
this.date = date;
}
#JsonProperty
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#JsonProperty
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public void setId(Long id) {
this.id = id;
}
}
I have already been to many tutorials but none of them really explains how to configure hibernate. Thank you in advance.
I have finally solved this problem, which was not a big deal actually. Just a small mistake as it was expected.
My problem was a Book class, IDE automatically imported the java library called Book in the LibraryApplication class, so DB was not mapping it.
On the other hand, in the Book class the named query should be as follows:
#NamedQuery(
name = "library.core.Book.findAll",
query = "SELECT b FROM Book b"
)
My mistake: I was writing Book with small letter.

JSON to POJO using Apache Camel and hibernate

Apache camel is using a route wich is listening to a specific url. the json from this url is then transformed to pojo classes and inserted in a mySQL database. Everything is working fine, except my foreign key still remains null. I'm using spring framework btw.
Here is the url where you can find the data:
https://builds.apache.org:443/job/Accumulo-1.5/api/json
Here is my routedefinition for camel
#Component
public class JenkinsConfigurationRouteBuilder extends SpringRouteBuilder {
private Logger logger = LoggerFactory.getLogger(JenkinsConfigurationRouteBuilder.class);
#Override
public void configure() throws Exception {
logger.info("Configuring route");
//Properties die hij niet vindt in de klasse negeren
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DataFormat jenkinsConfigFormat = new JacksonDataFormat(objectMapper, JenkinsConfiguration.class);
from("timer://foo?fixedRate=true&delay=0&period=200000&repeatCount=1")
.routeId("jsonToJenkinsConfiguration")
.setHeader(Exchange.HTTP_METHOD, constant("GET"))
.to("https://builds.apache.org:443/job/Accumulo-1.5/api/json")
.convertBodyTo(String.class)
.unmarshal(jenkinsConfigFormat) //instance van JenkinsConfiguration
.log(LoggingLevel.DEBUG, "be.kdg.teamf", "Project: ${body}")
.to("hibernate:be.kdg.teamf.model.JenkinsConfiguration");
}
}
My POJO class
#Entity(name = "jenkinsConfiguration")
public class JenkinsConfiguration extends Configuration implements Serializable {
#Column
#JsonProperty("displayName")
private String name;
#JsonProperty("healthReport")
#JsonIgnore
#LazyCollection(LazyCollectionOption.FALSE)
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = ("jenkinsConfig"))
private Collection<HealthReport> healthReport;
#JsonProperty("builds")
#JsonIgnore
#LazyCollection(LazyCollectionOption.FALSE)
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = ("jenkinsConfig"))
private Collection<Build> builds;
#JsonProperty("modules")
#JsonIgnore
#LazyCollection(LazyCollectionOption.FALSE)
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = ("jenkinsConfig"))
private Collection<Module> modules;
public JenkinsConfiguration() {
}
public JenkinsConfiguration(Collection<Build> builds, Collection<HealthReport> healthReport, Collection<Module> modules, String name) {
this.builds = builds;
this.healthReport = healthReport;
this.modules = modules;
this.name = name;
}
public Collection<Build> getBuilds() {
return builds;
}
public Collection<HealthReport> getHealthReport() {
return healthReport;
}
public Collection<Module> getModules() {
return modules;
}
public String getName() {
return name;
}
public void setBuilds(Collection<Build> builds) {
this.builds = builds;
}
public void setHealthReport(Collection<HealthReport> healthReport) {
this.healthReport = healthReport;
}
public void setModules(Collection<Module> modules) {
this.modules = modules;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
Let us take the builds for instance.
As you can see, this pojo class contains a list from builds. A JenkinsConfiguration can contain more builds. One build belongs to one JenkinsConfiguration.
This is my Build class:
#XmlRootElement(name = "builds")
#Entity(name = "build")
public class Build implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int Id;
#Column
#JsonProperty("number")
private Integer number;
#Column
#JsonProperty("url")
private String url;
#JsonBackReference
#OnDelete(action = OnDeleteAction.CASCADE)
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "jenkinsConfig")
private JenkinsConfiguration jenkinsConfig;
public Build() {
}
public Build(JenkinsConfiguration jenkinsConfig, Integer number, String url) {
this.jenkinsConfig = jenkinsConfig;
this.number = number;
this.url = url;
}
public int getId() {
return Id;
}
public JenkinsConfiguration getJenkinsConfig() {
return jenkinsConfig;
}
public Integer getNumber() {
return number;
}
public String getUrl() {
return url;
}
public void setId(int id) {
Id = id;
}
public void setJenkinsConfig(JenkinsConfiguration jenkinsConfig) {
this.jenkinsConfig = jenkinsConfig;
}
public void setNumber(Integer number) {
this.number = number;
}
public void setUrl(String url) {
this.url = url;
}
}
My question: how come that my foreign key is not set for the build class? it remains null.
Doe I need to update it manually or something? If so, how do I do that in spring?
Any help would me much appreciated!
Fixed it by updating the records in my database like so:
Camel:
from("hibernate:be.kdg.teamf.model.Build?delay=1s")
.routeId("buildFkBuild")
.startupOrder(3)
.shutdownRunningTask(ShutdownRunningTask.CompleteAllTasks)
.to("bean:buildFK?method=processBuild")
.log(LoggingLevel.DEBUG, "be.kdg.teamf", "Project: ${body}")
.to("hibernate:be.kdg.teamf.model.Build");
Bean:
#Consumed
public Build processBuild(Build build) {
//updaten van foreign key
build.setJenkinsConfig(jenkinsConfiguration);
return build;
}