How to populate values to Map of a POJO in MyBatis - mybatis

I have a Java class that looks like this.
class Student {
private String studeID;
private String UUID;
private Map<String,Object> attributes;
}
And I have SQL to get students as follows.
SELECT studeID, UUID, F_NAME, L_NAME, PHONE FROM STUDENTS;
Need to populate F_NAME, L_NAME, PHONE to Map<String,Object> attributes of class Student.
How can I achieve this in iBatis/MyBatis XML.

Related

Open JPA for an element of type Array

We have a requirement to store the weekdays against a particular site. Below is the table structure. I couldn't able to map the text[] to the entity property. We are using the open JPA for the repository. Can someone suggest the solution to have String[] in Entity class.
Table :
'''
site(id int, name varchar(50), weekdays text[]);
'''
Entity Class:
'''
#Entity
public class Site {
#Id
private Long id;
#Column
private String name;
#Column
private String[] weekdays;
}
'''

How can I change a value of an id attribute to its equivalent description in DTO class using mapstruct

I have a 1 entity class PersonEntity and corresponding to that I have Dto class
#Entity(value="person")
class PersonEntity{
String name;
String id;
}
**DTO**
class PersonDto{
String name;
String id;
String desc; (This is a lookup from a map with id attribute)
}
In my mapper class, I am able to change my entity list to Dto list with below code.
public interface MyMapper{
List<PersonDto> entityListToDtoList(<List<PersonEntity>)
}
How can I use my lookup map to get the description and set in my DTO class. I am not able to figure out how to determine the value with below code.
List<PersonDto> entityListToDtoList(<List<PersonEntity>,#Context Map<String,String> lookupMap)
You have to define the PersonEntity to PersonDto method and add a #Mapping with an expression for that. See the following example:
#Mapping( target = "desc", expression = "java(lookupMap.get(person.getId()))" )
PersonDto entityToDto(PersonEntity person, #Context Map<String, String> lookupMap);
List<PersonDto> entityListToDtoList(List<PersonEntity> persons, #Context Map<String, String> lookupMap);

Crieria API query using criteriabuilder.construct with a non existing relationship

Given this very simple DTO:
#Entity
public class Employee implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
#OneToOne
private Employee boss;
}
I'd like to make a query that gathers all employee names and their boss' id, put in a nice clean POJO:
public class EmployeeInfo {
private String name;
private Long bossId;
public EmployeeInfo(String name, Long bossId) {
this.name = name;
this.bossId = bossId;
}
}
This query should be of use:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<EmployeeInfo> query = cb.createQuery(EmployeeInfo.class);
Root<Employee> root = query.from(Employee.class);
query.select(
cb.construct(EmployeeInfo.class,
root.get("name").as(String.class),
root.get("boss").get("id").as(Long.class)));
result = em.createQuery(query).getResultList();
When a bossId is present in the employee column this works just fine. But when no boss id is set the record will be completly ignored. So how do i treat this non existing boss relation as null or 0 for the construct/multiselect?
In pure SQL it is easy:
SELECT name, COALESCE(boss_id, 0) FROM EMPLOYEE;
But for the love of god i cannot make the criteria api do this.
cb.construct(EmployeeInfo.class,
root.get("name").as(String.class),
cb.coalesce(root.get("boss").get("id").as(Long.class), 0L)));
The problem is that root.get("boss") generate query with cross join like this from Employee employee, Employee boss where employee.boss.id=boss.id. So records where employee.boss.id is null are ignored.
To solve the problem you should use root.join("boss", JoinType.LEFT) instead of root.get("boss")

JPA Add extra fields by calling a function

How can I add an extra column in JPA query?
Suppose we have a table "users" created by following pseudocode:
create table users(name,birthdate);
User jpa entity is something like this :
#Entity
#Table("users")
public class User {
#Basic
#Column
private String name;
#Basic
#Column
private Date birthDate;
#Transient
private int age;
//getters and setters are here
}
Note that the Age field is not exsists in the table
I want to write the following query in JQL using
entityManager.createQuery(jql)
and calculate age over the database
select u.*, sysdate-u.birthdate age from users
The problem is solved.
The query text is like :
String jql = "select NEW entity.User(u.id, u.name, u.birthDate, sysdate-u.birthDate as age) from User u";
and also a appropriate constructor is added to the entity
public User(int id, String name, Date birthDate, double age) {
this.id = id;
this.name = name;
this.birthDate = birthDate;
this.age = age;
}
and uses entitymanaget.createQuery(jql) instead of createNativeQuery
Usully i solve this problem using this way :
select new name.of.package.users(u.*, sysdate - u.birthdate as age) from users u;
Edit
It leads to ORA-00923: FROM keyword not found where expected My Query
text is : String jql = "select new entity.User(u.*, sysdate-u.birthdate as age) from User u";
The query contain an error in :
select new entity.User(u.*, sysdate-u.birthdate as age) from User u
//--------------------------------^^^
Possibly using a DB-View might help. Do you want the entity to be updateable? Would it be reasonable to have a "readonly"-entity derived from a kind of "maintenance"-entity which would contain the calculated columns by using a database-view as #Table?
create view usersview as name, birthdate, sysdate - birthdate as age from users;
Entity:
#Entity
#Table("usersview")
public class UserExtended extends User {
If you don't want two different Entity-Classes (even when one is derived from the other), there would be some exploration necessary how JPA allows updating on views, if the dbms supports it (oracle does), I have no experience in that, sorry.

Filtering a list in Objectify using Ref

How do i filter a list of an entity in Objectify which has Ref to another entity. The list should be filtered out based on a String field in the Ref entity.
public class AccountEntity extends BaseEntity {
#Index
private String accountName;
private String accountNo;
private String description;
private Integer displayOrderNo;
private Boolean contra = false;
private AccountingAccountType accountType;
#Index
private Ref<AccountGroupEntity> accountGroup;
#Ignore
private List<AccountEntryEntity> accountLedgerEntries;
public AccountEntity() {
}
this is ref entity
filter code
A ref is a key, so you can filter the key by passing in either a Key, Key<>, Ref<> or #Entity pojo.
You cannot however filter on a property of the entity that the key points to. To do this you'll need to denormalise that property into a separate indexed list in this entity, or create a lookup entity, similar to a join table.