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;
}
Related
I'm working on a simple todo app in which you can add dependencies between todo items which means you cannot change status to true(completed) if dependency item is not completed. The problem is when I delete an item which another item is dependent to, json still shows dependency between two items. I'll try to explain with an example; say you have item 1 and item 2. Item 1 is dependent to item 2 and you can't mark item 1 "completed" if item 2 is not completed. But if you delete item 2 then dependency between items is also gone. So after deleting item 2 I can change item 1's status to true but when I make a get request for item 1, json still shows dependency to item 2.
Here is my TodoItem class;
package com.erdemkara.todoapp.data.entity;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
import java.time.LocalDate;
import java.util.Set;
#Entity
#Table(name = "todo_items")
public class TodoItem {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(nullable = false)
private String name;
private String description;
#Column(nullable = false)
private LocalDate deadline;
#Column(nullable = false)
private boolean status;
#Column(name = "todo_list_id", nullable = false)
private int todoListId;
#OneToMany(mappedBy = "todoItem", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JsonManagedReference
private Set<Dependency> dependencies;
public TodoItem()
{}
public TodoItem(int id, String name, String description, LocalDate deadline,
boolean status, int todoListId, Set<Dependency> dependencies)
{
this.id = id;
this.name = name;
this.description = description;
this.deadline = deadline;
this.status = status;
this.todoListId = todoListId;
this.dependencies = dependencies;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public LocalDate getDeadline() {
return deadline;
}
public void setDeadline(LocalDate deadline) {
this.deadline = deadline;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
#JsonGetter("todo_list_id")
public int getTodoListId() {
return todoListId;
}
public void setTodoListId(int todoListId) {
this.todoListId = todoListId;
}
public Set<Dependency> getDependencies() {
return dependencies;
}
public void setDependencies(Set<Dependency> dependencies) {
this.dependencies = dependencies;
}
}
Dependency class;
package com.erdemkara.todoapp.data.entity;
import com.fasterxml.jackson.annotation.*;
import javax.persistence.*;
#Entity
#Table(name = "dependencies")
public class Dependency {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#JsonIgnore
private int id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "todo_item_id", nullable = false)
#JsonBackReference
private TodoItem todoItem;
#Column(name = "dependency_item_id", nullable = false)
private int dependencyItemId;
public Dependency()
{}
public Dependency(int id, TodoItem todoItem, int dependencyItemId)
{
this.id = id;
this.todoItem = todoItem;
this.dependencyItemId = dependencyItemId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public TodoItem getTodoItem() {
return todoItem;
}
public void setTodoItem(TodoItem todoItem) {
this.todoItem = todoItem;
}
public int getDependencyItemId() {
return dependencyItemId;
}
public void setDependencyItemId(int dependencyItemId) {
this.dependencyItemId = dependencyItemId;
}
}
Response for item 1 get request(item 1 is dependent to item 2 and 3);
{
"id": 1,
"name": "Item 1",
"description": "Study Collections",
"deadline": "2023-01-09",
"status": false,
"dependencies": [
{
"dependencyItemId": 3
},
{
"dependencyItemId": 2
}
],
"todo_list_id": 1
}
I get the same response before and after deleting item 2. But I want to get a response like this;
{
"id": 1,
"name": "Item 1",
"description": "Study Collections",
"deadline": "2023-01-09",
"status": false,
"dependencies": [
{
"dependencyItemId": 3
}
],
"todo_list_id": 1
}
How can I fix this?
EDIT: #Zychoo I use 2 different delete methods on Service layer. One is for deleting all dependencies for an item. The other one is to delete a specific dependency;
public void deleteDependencyByDependencyItemId(int todoItemId, int dependencyItemId) {
dependencyRepository.deleteByDependencyItemId(todoItemId, dependencyItemId);
}
public void deleteAllDependenciesByTodoItemId(int todoItemId) {
dependencyRepository.deleteAll(dependencyRepository.findAllByTodoItemId(todoItemId));
}
And this is the Repository Layer;
public interface IDependencyRepository extends CrudRepository<Dependency, Integer> {
#Modifying
#Transactional
#Query(value = "delete from dependencies d where d.todo_item_id=? and d.dependency_item_id =?", nativeQuery = true)
void deleteByDependencyItemId(int todoItemId, int dependencyItemId);
}
You could changed
public Set<Dependency> getDependencies() {
return dependencies;
}
to
public Set<Dependency> getDependencies() {
return dependencies.stream().filter(dependency -> "your condition for completion").collect(Collectors.toSet());
}
The ObjectMapper from spring-boot uses the getters to create a JSON. If your Dependency does not show up in the return value of your getter, it will not show up in the JSON response.
I reorganized delete method in TodoItem service layer from this:
public void deleteItemById(int id) {
todoItemRepository.deleteById(id);
}
to this:
public void deleteItemById(int id) {
todoItemRepository.deleteById(id);
dependencyService.deleteAllDependenciesByTodoItemId(id);
}
It deletes every dependency along with the item. Now it works as I expected. Thank you for the answers.
I have two tables, Enterprises and Appliance in unidirectional one to many association.
When I try to delete any enterprise, it deletes its corresponding appliances too, which is the expected behavior.
Now if I try to delete any appliance, its corresponding enterprise gets deleted as well!!
This is neither expected nor am I able to figure out how to solve this.
I wish that if I delete an Appliance only that appliance should get deleted not, the Enterprise the appliance belongs too!!
Enterprise Class:
#Entity
#Table(name="Enterprises")
public class Enterprises implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id", nullable=false, unique=true)
private Long id;
#Column(name="EntpName")
private String entpName;
#Column(name="ContactPerson")
private String contactPerson;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="CreatedDate", nullable=false)
private Date createdDate;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="ModifiedDate")
private Date modifiedDate;
public Enterprises() { }
public Enterprises(Long id) {
this.id = id;
}
public Enterprises(String entpName, String contactPerson) {
this.entpName = entpName;
this.contactPerson = contactPerson;
this.setCreatedDate();
}
// Getter and setter methods
public Long getId() {
return id;
}
public void setId(Long value) {
this.id = value;
}
public String getEntpName() {
return entpName;
}
public void setEntpName(String value) {
this.entpName = value;
}
public String getContactPerson() {
return contactPerson;
}
public void setContactPerson(String value) {
this.contactPerson = value;
}
public Date getCreatedDate() { return createdDate; }
#PrePersist
public void setCreatedDate() {
this.createdDate = new Date();
}
public Date getModifiedDate() { return modifiedDate; }
#PreUpdate
public void setModifiedDate() {
this.modifiedDate = new Date();
}
}
Appliance Class:
#Entity
#Table(name="Appliance")
public class Appliance {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id", nullable=false, unique=true)
private Long id;
#Column(name="ApplianceName")
private String AppName;
#Column(name="Parameter1")
private String param1;
#Column(name="Parameter2")
private String param2;
#Column(name="Parameter3")
private String param3;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="CreatedDate", nullable=false)
private Date createdDate;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="ModifiedDate")
private Date modifiedDate;
#ManyToOne(cascade = {CascadeType.REMOVE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
#JoinColumn(name="Enterprises_id", referencedColumnName = "id")
#OnDelete(action= OnDeleteAction.CASCADE)
private Enterprises enterprise;
public Enterprises getEnterprise() {
return enterprise;
}
public void setEnterprise(Enterprises enterprise) {
this.enterprise = enterprise;
}
// ------------------------
// PUBLIC METHODS
// ------------------------
public Appliance() { }
public Appliance(Long id) {
this.id = id;
}
public Appliance(String AppName, String param1, String param2, String param3) {
this.AppName = AppName;
this.param1 = param1;
this.param2 = param2;
this.param3 = param3;
this.setCreatedDate();
}
// Getter and setter methods
public Long getId() {
return id;
}
public void setId(Long value) {
this.id = value;
}
public String getAppName() {
return AppName;
}
public void setAppName(String value) {
this.AppName = value;
}
public String getparam1() {
return param1;
}
public void setparam1(String value) {
this.param1 = value;
}
public String getparam2() {
return param2;
}
public void setparam2(String value) {
this.param2 = value;
}
public String getparam3() {
return param3;
}
public void setparam3(String value) {
this.param3 = value;
}
public Date getCreatedDate() { return createdDate; }
#PrePersist
public void setCreatedDate() {
this.createdDate = new Date();
}
public Date getModifiedDate() { return modifiedDate; }
#PreUpdate
public void setModifiedDate() {
this.modifiedDate = new Date();
}
}
My controller:
ApplianceUserController:
#Controller
#RequestMapping("/")
public class ApplianceUserController {
#Autowired
private ApplianceRepository appliancerepo;
#Autowired
private UserRepository userrepo;
#RequestMapping(value = "{id}/list", method = RequestMethod.GET)
#ResponseBody
public LinkedList<List> listStuff(#PathVariable("id") Enterprises id) {
List<Appliance> appliances = appliancerepo.findApplianceByEnt_id(id);
List<Users> users = userrepo.findUsersByEnt_id(id);
LinkedList<List> together = new LinkedList<List>();
together.add(appliances);
together.add(users);
return together;
}
#RequestMapping(value="{idd}/appliance/add" , method = RequestMethod.POST)
#ResponseBody
Appliance addAppliance(#PathVariable("idd") Enterprises idd , #RequestBody Appliance appliance) {
appliance.setEnterprise(idd);
appliance.setCreatedDate();
return appliancerepo.save(appliance);
}
#RequestMapping(value = "appliance/update/{id}", method = RequestMethod.PUT)
#ResponseBody
Appliance updateAppliance(#PathVariable("id") Long id, #RequestBody Appliance appliance) {
Appliance applianceOld= appliancerepo.findById(id);
applianceOld.setAppName(appliance.getAppName());
applianceOld.setparam1(appliance.getparam1());
applianceOld.setparam2(appliance.getparam2());
applianceOld.setparam3(appliance.getparam3());
applianceOld.setModifiedDate();
return appliancerepo.save(applianceOld);
}
#RequestMapping(value = "appliance/delete/{id}", method = RequestMethod.DELETE)
#ResponseBody
void deleteAppliance(#PathVariable("id") Long id) {
appliancerepo.delete(id);
}
#RequestMapping(value = "appliance/{id}", method = RequestMethod.GET)
#ResponseBody
Appliance getA(#PathVariable("id") Long id) {
Appliance appliance=appliancerepo.findAppliance(id);
System.out.println(appliance);
return appliance;
}
}
PS: Yes, cascade update and delete is ON for the foreign keys in the MySql database!!!!
Please inform me, if you need any other code.
UPDATE:
SOLVED
For future reference by anyone:
Needed to remove the #OnDelete line and and the cascade property from #ManyToOne in the Appliance class!!
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.
I have the following (full) entity class.
public class StateTable implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "state_id", nullable = false)
private Long stateId;
#Column(name = "state_name", length = 45)
private String stateName;
#OneToMany(mappedBy = "stateId", fetch = FetchType.LAZY)
private Set<UserTable> userTableSet;
#OneToMany(mappedBy = "stateId", fetch = FetchType.LAZY)
private Set<City> citySet;
#OneToMany(mappedBy = "stateId", fetch = FetchType.LAZY)
private Set<Inquiry> inquirySet;
#OneToMany(mappedBy = "shippingState", fetch = FetchType.LAZY)
private Set<OrderTable> orderTableSet;
#OneToMany(mappedBy = "paymentState", fetch = FetchType.LAZY)
private Set<OrderTable> orderTableSet1;
#JoinColumn(name = "country_id", referencedColumnName = "country_id")
#ManyToOne(fetch = FetchType.LAZY)
private Country countryId;
public StateTable() {
}
public StateTable(Long stateId) {
this.stateId = stateId;
}
public Long getStateId() {
return stateId;
}
public void setStateId(Long stateId) {
this.stateId = stateId;
}
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
#XmlTransient
public Set<UserTable> getUserTableSet() {
return userTableSet;
}
public void setUserTableSet(Set<UserTable> userTableSet) {
this.userTableSet = userTableSet;
}
#XmlTransient
public Set<City> getCitySet() {
return citySet;
}
public void setCitySet(Set<City> citySet) {
this.citySet = citySet;
}
#XmlTransient
public Set<Inquiry> getInquirySet() {
return inquirySet;
}
public void setInquirySet(Set<Inquiry> inquirySet) {
this.inquirySet = inquirySet;
}
#XmlTransient
public Set<OrderTable> getOrderTableSet() {
return orderTableSet;
}
public void setOrderTableSet(Set<OrderTable> orderTableSet) {
this.orderTableSet = orderTableSet;
}
#XmlTransient
public Set<OrderTable> getOrderTableSet1() {
return orderTableSet1;
}
public void setOrderTableSet1(Set<OrderTable> orderTableSet1) {
this.orderTableSet1 = orderTableSet1;
}
public Country getCountryId() {
return countryId;
}
public void setCountryId(Country countryId) {
this.countryId = countryId;
}
#Override
public int hashCode() {
int hash = 0;
hash += (stateId != null ? stateId.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof StateTable)) {
return false;
}
StateTable other = (StateTable) object;
if ((this.stateId == null && other.stateId != null) || (this.stateId != null && !this.stateId.equals(other.stateId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "model.StateTable[ stateId=" + stateId + " ]";
}
}
I need only two properties from this class as a JSON response namely, stateId and stateName. The rest of the properties must be ignored from being processed/serialized by JSON.
I have tried to set json.excludeProperties to the json interceptor as follows.
#Namespace("/admin_side")
#ResultPath("/WEB-INF/content")
#ParentPackage(value="json-default")
public final class StateListAction extends ActionSupport implements Serializable, ValidationAware
{
#Autowired
private final transient SharableService sharableService=null;
private static final long serialVersionUID = 1L;
private Long id;
List<StateTable>stateTables=new ArrayList<StateTable>();
public StateListAction() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#JSON(name="stateTables")
public List<StateTable> getStateTables() {
return stateTables;
}
public void setStateTables(List<StateTable> stateTables) {
this.stateTables = stateTables;
}
#Action(value = "PopulateStateList",
results = {
#Result(type="json", name=ActionSupport.SUCCESS, params={"json.enableSMD", "true", "json.enableGZIP", "true", "json.excludeNullProperties", "true", "json.root", "stateTables", "json.excludeProperties", "userTableSet, citySet, inquirySet, orderTableSet, orderTableSet1, countryId", "validation.validateAnnotatedMethodOnly", "true"})})
public String populateStateList() throws Exception
{
System.out.println("countryId = "+id);
stateTables=sharableService.findStatesByCountryId(id);
return ActionSupport.SUCCESS;
}
}
The remaining properties are expected to be ignored after doing this but it doesn't seem to work. Number of SQL statements associated with all of the entity classes are generated which in turn causes other severe errors to occur like,
org.apache.struts2.json.JSONException: java.lang.IllegalAccessException: Class
org.apache.struts2.json.JSONWriter can not access a member of class
org.joda.time.tz.DateTimeZoneBuilder$PrecalculatedZone with modifiers "public"
What am I missing here? How to ignore all the properties except stateId and stateName?
I'm using Struts2-json-plugin-2.3.16.
You need to configure includeProperties in the json result. For example
#Result(type="json", params = {"contentType", "text/javascript", "includeProperties",
"stateTables\\[\\d+\\]\\.stateId,stateTables\\[\\d+\\]\\.stateName"})
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.