Read specific column data which is long type by using Spring Batch in Spring Boot - spring-boot

Folks..!!
Have a requirement to work on reading specific column data by using Spring batch. Well i am creating a spring batch application which has a requirement to read specific column.
In my csv file i have a column "msisdn", that field is mapped to an POJO. I want to read the values of "msisdn" no which is of Long data type.
well i am taking reference of below link.
read only selective columns from csv file using spring batch
Customer POJO
public class Customer {
private String id_type;
private String id_number;
private String customer_name;
private String email_address;
private LocalDate birthday;
private String citizenship;
private String address;
private Long msisdn;
private LocalDateTime kyc_date;
private String kyc_level;
private String goalscore;
private String mobile_network;
}
I am using a CustomMapper class to implement this feature. As you can see CustomMapper class implements FieldSetMapper type. fieldSet method returns String[] Array and msisdn is of Long type.Not able to understand how to get all values in msisdn column as fieldSet is only giving String[] type of data.
CustomMapper
============
public class CustomMapper implements FieldSetMapper<Customer> {
#Override
public Customer mapFieldSet(FieldSet fieldSet) throws BindException {
String[] custArray = null;
Customer customer = new Customer();
customer.setMsisdn(fieldSet.get);
return null;
}
}
please help me on this?

You can use fieldSet.readLong(int index) or fieldSet.readLong(String name) to select a field by name or index from the field set. Obviously this field should have been selected when parsing the file in your item reader.

Related

Spring Data JPA - Find all by nested list property

I'm trying to retrieve a list of products by one of their variants ids but I simply couldn't figure it out with nested classes and a list.
I've tried the method
List<Product> findAllByFooProductVariantsCodeIn(List<String> variantCodes);
It didn't work out as well.
public class Product extends DatabaseEntity {
private FooProduct fooProduct;
}
public class FooProduct {
private String title;
private String vendor;
private String productType;
private String tags;
private List<FooProductVariant> variants;
}
public class FooProductVariant {
private String productId;
private String title;
private String price;
private String variantCode;
}
An example of this could be 3 base Products with 3 variants
1st product ABC
2nd product RTY
3rd product XYZ
and the variantCodes of these products:
ABC-003,
RTY-001,
XYZ-002
the parameter variantCodes does contain all these variant codes and the method is expected to return 3 products as ABC, RTY, XYZ. Query needs to get into the nested FooProduct and after the FooProductVariant list inside it, and unnest the variant codes and find the Product from one of these variant Codes
Is this doable with Spring Data JPA?

Sort data by createDate

I have a set of data that I return in a method, how can I sort this data by createDate, I can do it using a stream, but the method returns a list, so I don’t want to use a stream, but if I can use a stream and return data in view list, can you show how?
public List<Mark> getMarksByUser(){
List<Mark> marks = markService.getMarksByUser(AuthenticationController.selfUserName());
}
sorting should be in this method
my mark entity with createDate
public class Mark extends BaseEntity<Integer> {
private String mark;
private String text;
private String sku;
private Date dateCreated;
private Date dateUpdated;
private Boolean deleted;
private String username;

Spring Data MongoRepository save causing Duplicate Key error

Here is the Entity:
#Document
#Data
public class ApplicationUser {
private String name;
#Indexed(unique = true)
private String email;
private String organization = null;
// other fields
}
I fetch this user using their email and then change their name. I use the autowired instance of ApplicationUserRepository.
ApplicationUser applicationUser = applicationUserRepository.findByEmail("abc#gmail.com");
applicationUser.setName("John Doe 2");
Then I try to update this entity again in the database:
applicationUserRepository.save(applicationUser);
I get a duplicate key error on the field email. Why is this happening?
As far as I get from the documentation, the save method updates the same document if the ObjectId is the same. Since I haven't changed the objectId then why is it trying to create a new ApplicationUser during saving?
I got the solution.
When creating the entity, I have to explicitly declare the Id.
Here is the Entity:
#Document
#Data
public class ApplicationUser {
#Id
private ObjectId _id;
private String name;
#Indexed(unique = true)
private String email;
private String organization = null;
// other fields
}
I had similar issue where I was retrieving by id and then trying to update the retrieved POJO and then save it back with MongoRepository.save() call. It was on MongoDB 4.x with Spring Boot 2.1.0. I added the #Transactional annotation to my service method and everything worked like a charm. The duplicate key exception on id field was resolved.

How to map java class to SQL view without id in spring data jpa?

Here's my class
public class JobSteps {
private String jobNo;
private String stepNumber;
private String stepDescription;
}
And here's my view
JobNo CHAR(7),
StepNumber TEXT,
StepDescription TEXT
I tried to annotate my class with Entity, specifying the table name, but spring keeps complaining about id, I added #Id to JobNo, but spring complains about type. Is there a way to manage it? I have no access to the view and can't change anything there.
Fo example, You can add JobStepId class and wrap tit with your char column.
#Embeddable
class JobStepId implements Serializable {
String jobIdString;
Integer jobId;
//implements equals and hashCode
}
Then your class could imbed it:
#IdClass(JobStepId.class)
public class JobSteps {
#Id
private JobStepId jobNo;
private String stepNumber;
private String stepDescription;
}

hibernate projection NumberFormatException for input string

I am using Spring MVC + Hibernate
Generic Dao
// getAll
#SuppressWarnings("unchecked")
public <T> List<T> getAll(Class<T> entityClass) throws DataAccessException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(entityClass);
return criteria.list();
}
#Controller
#RequestMapping(value = "/genCompanyInfoUpdate", method = RequestMethod.POST)
public String genCompanyInfoUpdate(Model model) {
List<GenCountryModel> countryList=pt.getAll(GenCountryModel.class);
List<GenCurrencyModel> currencyList=pt.getAll(GenCurrencyModel.class);
GenCompanyInfoModel companyInfo=pt.getById(GenCompanyInfoModel.class, 1);
model.addAttribute("countryList", countryList);
model.addAttribute("currencyList", currencyList);
model.addAttribute("companyInfo", companyInfo);
return "gen/genCompanyInfoUpdate";
}
JSP
<c:if test="${not empty currencyList}">
<c:forEach items="${currencyList}" var="get" varStatus="counter">
<ct:Options setValue="${get.id}" setName="${get.isoCode}" selected="${companyInfo.genCurrencyModel.id}" setState="1" />
</c:forEach>
</c:if>
All working well but when I change and use Projection in Method as the following , then it give exception
java.lang.numberformatexception for input string id
java.lang.numberformatexception for input string isoCode
Changes: ProjectionList use in Method
#SuppressWarnings("unchecked")
public <T> List<T> getAll(Class<T> entityClass, String[] nameList) throws DataAccessException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(entityClass);
ProjectionList pl = Projections.projectionList();
for (int i=0; i<nameList.length; i++) {
pl.add(Projections.property(nameList[i].toString()));
}
criteria.setProjection(pl);
return criteria.list();
}
Changes in #Controller passing List [GenCurrencyModel]
#RequestMapping(value = "/genCompanyInfoUpdate", method = RequestMethod.POST)
public String genCompanyInfoUpdate(Model model) {
String []list={"id","isoCode"};
List<GenCountryModel> countryList=pt.getAll(GenCountryModel.class);
List<GenCurrencyModel> currencyList=pt.getAll(GenCurrencyModel.class,list);
GenCompanyInfoModel companyInfo=pt.getById(GenCompanyInfoModel.class, 1);
model.addAttribute("countryList", countryList);
model.addAttribute("currencyList", currencyList);
model.addAttribute("companyInfo", companyInfo);
return "gen/genCompanyInfoUpdate";
}
Same JSP
<c:if test="${not empty currencyList}">
<c:forEach items="${currencyList}" var="get" varStatus="counter">
<ct:Options setValue="${get.id}" setName="${get.isoCode}" selected="${companyInfo.genCurrencyModel.id}" setState="1" />
</c:forEach>
</c:if>
GenCurrencyModel
public class GenCurrencyModel implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "CURRENCYID")
#GeneratedValue
private long id;
#Column(name = "CODE")
private String currencyCode;
#Column(name = "DESCRIPTION")
private String currencyDesc;
#Column(name = "ISACTIVE")
private int isActive;
#Column(name = "MADELETE")
private int markAsDelete;
#Column(name = "ISOCODE")
private String isoCode;
#Column(name = "CURRENCYUNIT")
private String currencyUnit;
#Column(name = "CONNECTOR")
private String connector;
#Column(name = "SUBUNIT")
private String subUnit;
#Column(name = "RECENTUSERID")
private long recentUserId;
#Column(name = "RECENTUSERIP")
private String recentUserIp;
#Column(name = "DATETIME")
private Date dateTime;
#Column(name = "ISUPDATED")
private int isUpdated;
private GenCompanyInfoModel genCompanyInfoModel;
public GenCurrencyModel() {
super();
}
//Getter Setter
}
I check the query from log file . it successfully execute
and when I remove the following line from jsp page, then there is no any exception
<ct:Options setValue="${get.id}" setName="${get.isoCode}"
Note: ct:Options is a custom JSP tag, that just print values, nothing special
After Projection the result of query is as follow
Hibernate: select this_.CURRENCYID as y0_, this_.ISOCODE as y1_ from GENCURRENCY this_
and both returning the list , and I have check both of size(), the size is also same !
Update me !
Typically, when using a projection list of specific properties in Hibernate, you won't be able to cast the query result as an entity type, at least not in the older versions of Hibernate I'm familiar with (i.e. 3.2.x). Instead, the default return type will be a List<Object[]> (when calling Criteria#list), where each array represents a tuple of the properties you specified in the projection list. (You can tell Hibernate to change the return type by giving the Criteria a ResultTransformer, but that may cause more confusion.) So instead of expecting partially-hydrated entities of type T and calling its getter methods (via JSTL expression), expect an array of Objects and get each property value by index (based on the order of the properties in the projection list).
Otherwise, it appears that you're passing the string values "id" and "isoCode" to your ct tag library (instead of the id and isoCode field values that you want), which I assume is expecting strings that can be parsed into numbers using something like Integer#parseInt(String), and this is causing the NumberFormatExceptions.
If this doesn't help, can you please provide more information? Specifically:
What are the property names you're specifying in the projection list?
What object types are those properties mapped as in the entity class? Providing the full entity mapping would help.
Is the ct:Options a custom JSP tag? If so, can you provide the logic of the tag class?

Resources