Create "Composite Global Secondary Index" in dynamoDB - java

I need to create a composite GSI based on 3 different fields and query the data. I cannot find any resource which can point me to the correct direction and usage of this. Would appreciate some help on how this can be achieved ?
The table is as below:
#Data
#NoArgsConstructor
#DynamoDBTable(tableName = TABLE_NAME)
public class MyTable {
#DynamoDBHashKey(attributeName = NAME)
private String name;
private Person person;
}
Person.java
public class Person {
private String name;
private String age;
private Gender gender; //Gender is an enum : MALE, FEMALE, OTHER
private String occupation;
.
.
.
and so on
}
Do I need to create another object like PersonV2 and then create an index on it or it should be done in a different way ?
APPROACH :
public class PersonV2 {
private String name;
private String age;
private Gender gender;
}
and the my table will look like this ?
#Data
#NoArgsConstructor
#DynamoDBTable(tableName = TABLE_NAME)
public class MyTable {
#DynamoDBHashKey(attributeName = NAME)
private String name;
private Person person;
#DynamoDBIndexHashKey(attributeName = MY_INDEX_ATTRIBUTE_NAME, globalSecondaryIndexName = MY_INDEX_NAME)
private PersonV2 personV2;
}
Is this the correct way to handle this ?

Related

What object should I POST in Spring Boot REST API?

I have a Hibernate model with id, name and surname. I am using it to get data from the database and then at the GET end-point is this one:
#GetMapping(value = "/contacts", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Contact> allContacts() {
return contactService.findAll();
}
As you can see it returns the Contact object. Actually it is a Hibernate entity.
The problem is that when I use this code
#PostMapping("/contacts")
public Contact createContact(Contact contact) {
return contactService.createContact(contact);
}
it asks not only name and surname but also the id. POST methods should not ask for id since they are not created yet. What should I do so that it doesn't ask for an id?
Edit: Here is the Contact.java class
import lombok.Data;
import javax.persistence.*;
#Entity
#Data
public class Contact {
public Contact() {
}
public Contact(Integer id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(columnDefinition = "serial")
private Integer id;
private String name;
private String surname;
}
Define a ContactInput class that only has the attributes you want the user to input and then create some mapping code that creates a valid Contact based on the ContactInput.
You should create ContactDto class
#Data
public ContactDto class {
private String name;
private String surname;
}
In #PostMapping you are gonna get ContactDto from the user. You cannot saved ContactDto into your database. So you need to map ContactDto to Contact. What you can do is simply create ContractMapper class.
public static contactDtoToEntity(ContactDto dto){
Contact dbContact = new Contact();
dbContact.setName(dto.getName());
dbContact.setSurname(dto.getSurname());
return dbContact;
}
Before you saved the contact in your database in service layer, you need to map it and then save. Id is gonna be generated in the database.

Can you help to understand how to use JOIN with spring-repository?

I want to understand how to use JOIN with JPA-spring-repositories.
There are two tables Man and Car
Man
varchar(25) manId primary key not null
varchar(25) name
varchar(25) surname
varchar(25) modelCar
Car
varchar(25) carId primary key not null,
varchar(25) color,
varchar(25) model;
And visualisation:
Man
mainId name surname modelCar
=====================================
111-1 Natasha Smith reno-123
111-2 Maria John mazda-214
Car
carId color model
============================
as-aw red reno-123
os-dz black mazda-214
sa-aa yeallow porche-1
Relation is one-to-one
My entities are
#Entity
#Table
#Getter #Setter #NoArgsConstructor
class ManRecord{
private String manId;
private String surname;
private String modelCar;
}
#Entity
#Table
#Getter #Setter #NoArgsConstructor
class CarRecord{
private String carId;
private String color;
private String model;
}
So, I need to write JPA-repositories to execute result of join:
name, surname and car-color:
select m.name, m.surname, c.color from Man m left join Car c on m.modelCar=c.model;
Can you help me with it?
I tried to
#Repository
public interface ManRepository extends CrudRepository<Man, String>{
#Query("select m.name, m.surname, c.color from Man m left join Car c on m.modelCar=c.model", nativeQuery=true)
List<Object> agregateData();
}
but I don't want to get just Object.
and, i tried someone with #OneToOne, but it doesn't help to for me
First of all it's not a good idea to join these entities through a model of the car - each man can have any cars so this join is not representative. The best way is to add a r_man_id into a Car table. It'll allow you to identify a car's owner.
After that you can add a unidirectional #OneToMany relation between them:
#Entity
#Table
#Getter #Setter #NoArgsConstructor
class ManRecord{
#JoinColumn(name = "r_man_id", referencedColumnName = "manId")
private List<CarRecord> cars = new ArrayList<>();
private String manId;
private String surname;
private String modelCar;
}
#Entity
#Table
#Getter #Setter #NoArgsConstructor
class CarRecord{
private String carId;
private String color;
#Column(name="r_man_id")
private Long refManId;
private String model;
}
Then create a model that you need:
class ManWithCarObject {
String name;
String surename;
String color;
/**
* Default
**/
public ManWithCarObject(){
}
public ManWithCarObject(String name, String surename, String color) {
this.name = name;
this.surename = surename;
this.color = color;
}
// other methods
}
And the repo then will be:
#Repository
public interface ManRepository extends CrudRepository<Man, String>{
#Query("select new com.contoso.model.ManWithCarObject(m.name, m.surename, m_c.color) from ManRecord m inner join m.cars m_c where m.manId = m_c.refManId")
List<ManWithCarObject> agregateData();
}

JPQL - How can I get an extra param inside my entity?

I am new to JPQL and I am trying to get an extra parameter that is not in the entity, but I am not finding how to do it.
Through searched here in the forum I found out that some uses a DTO for it, but I am not knowing how to apply that.
Here is my entity:
#Entity
#Table(name = "person")
public class Person implements Serializable {
private int id;
private String name;
private String email;
private int age;
...
}
And my JPQL:
SELECT COUNT(a.name) as countOfNames, a FROM Person a WHERE a.name like :name
How can I get the countOfNames result inside of myentity object since it is not a column?
The simplest way is to use a constructor expression
package com.entites
public class PersonDto {
private Person person;
private Integer countOfNames;
public PersonDto(Person person, Integer countOfNames) {
this.person = person;
this.countOfNames = countOfNames;
}
}
select new com.entites.PesronDto(a, count(a.name))
from Person a
where a.name like :name

hibernate mapping to a class with a list

I have 3 classes as shown below.
#Entity
public class Family (
#Id
private String familyName;
private int size;
#OneToMany
protected VehiclesList getVehiclesList()
// getters and setters
)
public class VehiclesList (
private List<Vehicle> vehicles;
#Transient
private int totalInsuranceCost
// getters and setters
}
#Entity
public class Vehicle (
#Id
private String plateNumber;
private String model;
private String color;
// getters and setters
)
I want to create two tables. First one is "Family" with columns as "size", etc. This is easy enough. Second, I want to create a "Vehicle" table with reference to Family. This table should have the following columns:
plateNumber
FamilyName
model
color
I would like the Family class to reference the VehiclesList class, so that I can access information from the VehiclesList class. None of the data in the VehiclesList class will be persisted to the database - only the vehicles. How can I do this?
VehicleList is not an entity so you cannot use OneToMany on it.
totalInsuranceCost should not be a property like this but more something for a service method like
VehicleService.calculateTotalInsuranceCostForFamily (String familyName).
Your family entity then becomes:
#Entity
public class Family (
#Id
private String familyName;
private int size;
#OneToMany(mappedBy = "family")
private List<Vehicle> vehicles;
// getters and setters
)

MySQL query / Hibernate Mapping not giving expected results

In my database, each user has a department and a userlevel. These are denoted in the users table with their department_id and their userlevel_id. The corresponding User java classes also has a department and userlevel field.
I need to select all the users from my db with a given username and password, and automatically map their department and userlevel object to their User object.
I have my Users, Departments and Userlevels class (automatically generated by hibernate pojo mapping) as follows:
public class Users implements java.io.Serializable {
private Integer id;
private Departments departments;
private Userlevels userlevels;
private String username;
private String password;
private String salt;
private String email;
private String firstName;
private String lastName;
public Users() {
}
//Getters and setters
}
public class Departments implements java.io.Serializable {
private Integer id;
private String name;
public Departments() {
}
//Getters and Setters
}
}
public class Userlevels implements java.io.Serializable {
private Integer id;
private String name;
public Userlevels() {
}
//Getters and Setters
}
}
I have an SQL query as such:
SQLQuery q = session.createSQLQuery("SELECT u.*,d.*,ul.* FROM users u, departments d, userlevels ul WHERE u.department_id=d.id AND u.userlevel_id=ul.id AND u.username=? AND u.password=?");
q.setString(0, "usernameToGet");
q.setString(1, "passwordToGet");
q.addEntity("u", Users.class);
q.addJoin("dept", "u.departments");
q.addJoin("ulevels", u.userlevels");
List<Users> users = q.list();
Right now I'm getting the correct User object with its corresponding department object, but the userlevels object is returning null....
Any help would be appreciated, Thanks!!

Categories