Nulls and Empty collections are stored in the database of my custom mapper - jackson

I have a custom ObjectMapper that deserializes Product and Order objects. It works fine but it stores and returns nulls in the Mongodb database. Here is my configuration. In my implementation of the custom serializers, I return an empty list/map for empty collections.
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.stereotype.Component;
import java.text.DateFormat;
import java.util.Locale;
#Component("retailObjectMapper")
public class RetailObjectMapper extends ObjectMapper {
public RetailObjectMapper() {
setDateFormat(DateFormat.getDateTimeInstance(DateFormat.DEFAULT,
DateFormat.DEFAULT, Locale.US));
SimpleModule module = new SimpleModule();
module.addDeserializer(Product.class,new ProductDeserializer(Product.class));
module.addDeserializer(Order.class,new OrderDeserializer(Order.class));
setSerializationInclusion(JsonInclude.Include.NON_NULL);
setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
registerModule(module);
}
}
Unfortuantely, the fields not populated return null and empty collections also return null. I have no idea why this is happening, help please.

Related

Is it possible to use Native SQL queries using micronaut hibernate-gorm?

I've created micronaut project using hibernate-gorm which gives me GORM and Groovy functionality but when it does not have groovy.sql.Sql class and if i inject DataSource then it's not working too. Is it possible to use native SQL queries with micronaut hiberate-gorm?
Yes, it is possible. See the example:
import grails.gorm.annotation.Entity
import grails.gorm.hibernate.HibernateEntity
#Entity
class Planet implements HibernateEntity<Planet> {
String name
}
In this case it is important to implement HibernateEntity and then you will have findWithSql method available as it is shown in the unit test below implemented using Spock framework:
import grails.gorm.transactions.Transactional
import io.micronaut.test.annotation.MicronautTest
import spock.lang.Specification
#MicronautTest
class PlanetSpec extends Specification {
#Transactional
void 'Planet is found when using native query'() {
given:
new Planet(name: 'Mars').save()
new Planet(name: 'Earth').save(flush: true)
when:
def actual = Planet.findWithSql("select * from planet p where p.name = 'Mars'")
then:
actual.name == 'Mars'
}
}
I know that there is a SQLQuery method in hibernate that runs native query against database engine. have you tried it?

Deserializing guava optional<long> is failing

I am serializing a guava optional using jackson(version:2.9.4).
When i am deserializing, i am getting below exception:
Cannot deserialize instance of 'java.lang.Long' out START_OBJECT token.
When i debug the value during deserialization, i noticed that the value is coming as "Optional(present=true)" rather than the value present inside Optional.
I looked at the object mapper, and "GuavaModule()" is already being registered with the object mapper.
Please let me know if i am missing anything.
With registering the GuavaModule of
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId>
</dependency>
…and the following bean…
import com.google.common.base.Optional;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#NoArgsConstructor
public class GuavaBean {
private Optional<Long> abc;
}
…this gives me a green test…
import static org.assertj.core.api.Assertions.assertThat;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
[…]
#Test
public void guava() throws JsonParseException, JsonMappingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new GuavaModule());
GuavaBean bean = new GuavaBean(Optional.of(9l));
String beanSerialized = objectMapper.writeValueAsString(bean);
assertThat(beanSerialized).isEqualTo("{\"abc\":9}");
GuavaBean optLong = objectMapper.readValue(beanSerialized, GuavaBean.class);
assertThat(optLong.getAbc().get()).isEqualTo(9);
}
However, if I accidentally use java.util.Optional instead of com.google.common.base.Optional, then the beahviour is exactly like you wrote.

Component objects instead of page objects in selenium

One of the most popular patterns in testing based on selenium is page object. Unfortunately, we often need to duplicate code if we use it as is. Consider the following situation:
We use UI framework, with common component, say some fancy table
Table is quite complicated, has filtering, sorting, searching
The table is used on several pages in the app
Is there any existing infrastructure to create more granular component objects instead of page objects either in selenium or in a thrid party lbirary?. I mean, annotations, and related infrastructure?
Appium which is the mobile implementation of selenium webdriver has a concept of widgets which is an extension of pageobjects. There is a Widget class which allows one to search relative to an element including in a web browser. You can check this out in the appium source test section. Have a look in the package io.appium.java_client.pagefactory_tests.widgets. This supports the FindBy annotation and WebElement construct and the PageFactory initialization.
So instead of using
#FindBy(.......)
private WebElement myTable;
you can use
#FindBy(container of the table....)
private Table myTable;
Table class can now have all the relevant variables and methods.
Part of POM.xml
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>2.53.1</version>
</dependency>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>4.1.2</version>
</dependency>
Test Class --
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.PageFactory;
public class WidgetBrowTest {
#Test
public void test() {
System.setProperty("webdriver.chrome.driver", "E:/Software Testing/Selenium/Jars/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://stackoverflow.com/");
SOHome soHome = new SOHome(driver);
PageFactory.initElements(new AppiumFieldDecorator(driver), soHome);
//Below two are from widget - First question in stackoverflow homepage
System.out.println(soHome.getFirstQues().getQuesTitle());
System.out.println(soHome.getFirstQues().getQuesTags());
//Below two are from home page
System.out.println(soHome.getLogoText());
System.out.println(soHome.getMenuText());
}
}
StackOverflow Home -
import java.util.List;
import java.util.stream.Collectors;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class SOHome {
#FindBy(css="div[id='hlogo'] > a")
private WebElement logo;
#FindBy(xpath="//div[#id='hmenus']//li/a")
private List<WebElement> menuOpt;
#FindBy(css="div[class='summary']")
private SOQuesWidget firstQues;
private WebDriver driver;
public SOHome(WebDriver driver) {
this.driver = driver;
}
public String getLogoText() {
return logo.getText();
}
public List<String> getMenuText() {
return menuOpt.stream().map(t -> t.getText()).collect(Collectors.toList());
}
public SOQuesWidget getFirstQues() {
return firstQues;
}
}
Question Widget - First Question
import java.util.List;
import java.util.stream.Collectors;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import io.appium.java_client.pagefactory.Widget;
public class SOQuesWidget extends Widget {
#FindBy(css="a[class='question-hyperlink']")
private WebElement quesTitle;
#FindBy(xpath=".//div[starts-with(#class,'tags')]/a")
private List<WebElement> quesTags;
protected SOQuesWidget(WebElement element) {
super(element);
}
public String getQuesTitle() {
return quesTitle.getText();
}
public List<String> getQuesTags() {
return quesTags.stream().map(t -> t.getText()).collect(Collectors.toList());
}
}
Page objects is kind of a misnomer. They don't have to be specifically full pages to follow the page object model. I would create a Table class (page object) that contains all of the locators and methods for the Table object and then include it in the pages/page objects where it appears.
For example, if the home page contains a table object, then the HomePage class would reference the Table class.

JsonIgnoreProperties not working

I have the following simple class:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
#JsonIgnoreProperties({ "thirdField" })
public class Message {
private TypeA type;
private String producer;
//Getters and Setters
}
in my test class
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
public void testMethd() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(MapperFeature.USE_ANNOTATIONS, true);
Class<T> instanceType = Message.class;
String msgBody = "{\"producer\": \"clientApp\", \"type\": \"aType\", \"thirdField\": []}";
objectMapper.readValue(msgBody, instanceType);
}
}
All I am trying to do is to convert the above json string into Message class and ignore the 'thirdField'. But I keep getting
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "thirdField" (class Message), not marked as ignorable (2 known properties: , "type", "producer"])
You've mixed different versions of Jackson.
Notice that you import JsonIgnoreProperties from org.codehaus.jackson.annotate (version 1.x)
while you're using ObjectMapper from com.fasterxml.jackson.databind (version 2.x).
Try using the last Jackson version (2.4):
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
#JsonIgnoreProperties({"id"})
Here you can find an example where it's implement using version 2.4:
http://www.ibm.com/developerworks/java/library/j-hangman-app/index.html
I found a Solution to this.
Try to add
#JsonSerialize(include= JsonSerialize.Inclusion.NON_EMPTY)
About your class
#JsonSerialize(include= JsonSerialize.Inclusion.NON_EMPTY)
class ResponseModel {
//your properties here
#JsonIgnoreProperties("messageList","contactList","sender")
var contactList= ArrayList<ContactModel>()
}
That will solve your issue buddy.
It didn't work for me any of the above answers, i found a workaround that I have reinitialized the object and values (copied the object).

How to get class attributes by using a custom object's accessors when the object is selected in a JComboBox?

I need help with using JComboBox: I have an ArrayList which I load into my JComboBox.
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class JFrameOrder extends JFrame {
ArrayList <Customer> cust = new ArrayList<Customer>();
public JFrameOrder() {
initComponents();
Inventory.createCustomers();
cust = Inventory.customerList();
jCboCustName.addItem("");
for (Customer c : cust){
jCboCustName.addItem(c);
}
The Inventory class has a method which creates the ArrayList - customer list.
The Customer class has two fields: int custID and String custName.
It also has accessors and mutators.
I can get the JComboBox to show the name by Overriding ToString.
I want to update a JLabel to show the corresponding custID based on the selection.
If the jCboCustName.getSelectedItem() returns an object, shouldn't I be able to use the object's accessors and mutators? After all I did load the element in as an Object. Please help.
Thanks in advance.