Project data from different tables to a model - spring-data-jpa

I defined my model classes like below.
#Entity
#Table(name = "my_employee")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
#OneToMany(cascade = CascadeType.ALL)
#JoinTable(name = "emp_address_mapping", joinColumns = #JoinColumn(name = "emp_id"), inverseJoinColumns = #JoinColumn(name = "address_id"))
private List<Address> addresses = new ArrayList<Address>();
.......
.......
}
#Entity
#Table(name = "my_address")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String country;
.....
.....
}
public class EmployeeDetails {
private int empId;
private String name;
private String country;
......
......
}
How can I write a query using #Query annotation to populate all the EmployeeDetails.
public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
#Query("SELECT new com.sample.app.model.EmployeeDetails......")
List<EmployeeDetails> getEmployeeDetails();
}

Create the constructor in EmployeeDetails
public EmployeeDetails(int id,String name,String country){
this.id=id;
this.name=name;
this.country=country;
}
Try this query
To get all employee details:
SELECT new com.sample.app.model.EmployeeDetails(e.id,e.name,a.country) from Employee e,Address a

Related

How to add new records to a field with #OneToOne in spring Data?

I am making a jsf + spring application.
The database contains a table of games and it is displayed on one of the pages of the site.
Each game has a genre list and development status. These fields are annotated with #OneToMany and #OneToOne respectively and are also tables in the database.
But here's the question: How do I add new games now? How do I initialize these fields? Because the only way I see is to create a new genre for a new game every time. That is, even if game A and games B are of the same genre, then I have to create two different unique genres, not one.
And how to initialize these fields from JSF?
For example from the <p: selectOneMenu> tag
game.java
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "game")
public class Game
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "name")
private String name;
#Column(name = "budget")
private String budget;
#Column(name = "profit")
private String profit;
#Column(name = "number")
private String number;
#OneToOne(optional = false, cascade = CascadeType.REFRESH)
#JoinColumn(name = "platform")
private Platform platform;
#OneToOne(optional = false, cascade = CascadeType.REFRESH)
#JoinColumn(name = "status")
private Status status;
#Column(name = "start")
private Date start;
#Column(name = "end")
private Date end;
#OneToMany(fetch = FetchType.EAGER)
#JoinTable(name = "game_genre",
joinColumns = #JoinColumn(name= "game_id"),
inverseJoinColumns = #JoinColumn(name= "genre_id"))
private List<Genre> listGenre;
public void update(Game new_game)
{
this.name = new_game.name;
this.budget = new_game.budget;
this.profit = new_game.profit;
this.number = new_game.number;
this.platform = new_game.platform;
this.status = new_game.status;
this.start = new_game.start;
this.end = new_game.end;
}
}
development status
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "status")
public class Status implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "Название")
private String Name;
#Column(name = "Описание")
private String description;
public void update(Status new_game)
{
this.description = new_game.description;
this.Name = new_game.Name;
}
}
genre:
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "genre")
public class Genre implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "description")
private String description;
public void update(Genre new_game)
{
this.name = new_game.name;
this.description = new_game.description;
}
}
Bean
#Component(value = "listgames")
#SessionScope
public class GamesView {
#Autowired
private GamesService gamesService;
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
private List<Game> All_games = new ArrayList<Game>();
private Game newGame=new Game();
public Game getNewGame() {
return newGame;
}
public void setNewGame(Game newGame) {
this.newGame = newGame;
}
public void onRowEdit(RowEditEvent event) {
Game new_game=(Game)event.getObject();
All_games.get(new_game.getId()-1).update(new_game);
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "INFO", "X/Y edit successful!");
FacesContext.getCurrentInstance().addMessage(null, msg);
int i=0;
i++;
}
public void createNew() {
gamesService.addBank(newGame);
newGame = new Game();
}
public List<Game> getAll_games() {
return gamesService.getAll();
}
public void setAll_games(List<Game> all_games) {
All_games = all_games;
}
}

Spring Boot : Building object Rest API

I created 4 classes for 3 tables. Those tables are built to store orders with products.
My first entity is orders :
#Entity
#Table(name="orders")
public class OrderEntity implements Serializable {
...
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
private UserEntity seller;
private String paymentMode;
private double totalAmount;
#OneToMany(mappedBy = "pk.order")
private List<OrderProductEntity> orderProducts;
#DateTimeFormat
private Date createdAt;
...
}
My second entity is products:
#Entity
#Table(name="products")
#Getter #Setter
public class ProductEntity implements Serializable {
...
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String productKeyId;
#ManyToOne
#JoinColumn(name = "category_id")
private CategoryEntity category;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private double price;
#Column(nullable = false)
private int availableQty;
#JsonManagedReference
#OneToMany(mappedBy = "pk.product", fetch = FetchType.EAGER)
#Valid
private List<OrderProductEntity> orderProducts;
...
}
I also define the pivot table in the OrderProductEntity:
#Entity
#Table(name="order_product")
#Getter #Setter
public class OrderProductEntity {
#EmbeddedId
#JsonIgnore
private OrderProductPK pk;
#Column(nullable = false)
private Integer quantity;
// default constructor
public OrderProductEntity(){}
public OrderProductEntity(OrderEntity order, ProductEntity product, Integer quantity) {
pk = new OrderProductPK();
pk.setOrder(order);
pk.setProduct(product);
this.quantity = quantity;
}
}
And I defined the PK of this table :
#Embeddable
#Getter #Setter
public class OrderProductPK implements Serializable {
#JsonBackReference
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "order_id")
private OrderEntity order;
#ManyToOne(optional = false, fetch = FetchType.LAZY)
#JoinColumn(name = "product_id")
private ProductEntity product;
}
Now my issue is to return the data to the front office by a web service Rest.
I created a model that represent what i want to obtain as result.
public class OrderRest {
private String orderKeyId;
private String paymentMode;
private double totalAmount;
private List<ProductRest> orderProducts;
private UserRest seller;
private Date createdAt;
}
And :
public class ProductRest {
private String productKeyId;
private String name;
private double price;
private int qty;
private String imgPath;
private CategoryRest category;
}
In my controller i want to return an OrderRest object :
public List<OrderRest> getOrders() {
List<OrderRest> returnValue = new ArrayList<>();
List<OrderDto> orderDtos = orderService.getOrders();
// loop the result
for (OrderDto orderDto : orderDtos) {
OrderRest orderRest = new OrderRest();
ModelMapper modelMapper = new ModelMapper();
orderRest = modelMapper.map(orderDto, OrderRest.class);
returnValue.add(orderRest);
}
return returnValue;
}
THis method map the List of OrderRest and call the service layer :
public List<OrderDto> getOrders() {
List<OrderDto> returnValue = new ArrayList<>();
Iterable<OrderEntity> orderEntities = orderRepository.findAll();
ModelMapper modelMapper = new ModelMapper();
for(OrderEntity orderEntity: orderEntities) {
OrderDto orderDto = new OrderDto();
UserDto userDto = orderDto.getSeller();
List<OrderProductDto> orderProductDtos = orderDto.getOrderProducts();
orderDto = modelMapper.map(orderEntity, OrderDto.class);
returnValue.add(orderDto);
}
return returnValue;
}
With OrderDto :
public class OrderDto implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private Long id;
private String orderKeyId;
private String paymentMode;
private double totalAmount;
private List<OrderProductDto> orderProducts;
private UserDto seller;
private Date createdAt;
}
And OrderProductDto :
public class OrderProductDto implements Serializable {
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private String productKeyId;
private String name;
private Integer price;
private Integer qty;
private String imgPath;
private CategoryDto category;
}
My issue is concerning what i return from the REST API :
my product list returns nothing :
"orderProducts": [
{
"productKeyId": null,
"name": null,
"price": 0.0,
"qty": 0,
"imgPath": null,
"category": null
},...
]

JPA Entity mapping for join columns

I have three tables EmployeeDepartment, EmployeeGroup and EmpplyeeDetails Table. EmployeeDepartment table has primary key departmentId and a column groupId, EmployeeGroupTable has primary key groupid which should be generated from databse sequence GroupIdGenerator.
EmployeeDetails have two primary keys as groupid and employeeid. Groupid should be same as of the previous table
These values in all table should insert in one transaction.
Can you help me with correct JAP Entity mapping?
I already tried with different combination of Generated value and Sequence generator but not able to save the data into table.
#Entity
#Table(name="EMPLOYEE_DEPARTMENT")
public class EmployeeDepartment {
#Column(name = "DEPARTMENT_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"departmentid-gen")
#Id
#NotNull
#SequenceGenerator(name = "departmentid-gen", sequenceName =
"DEAPARTMENT_ID_GENERATOR" )
private long departmentId;
#OneToOne(mappedBy = "employeeGroup")
private EmployeeGroup employeeGroup;
}
#Coulmn(name="GROUP_ID")
private long groupId;
#Entity
#Table(name="EMPLOYEE_GROUP")
public class EmployeeGroup {
#Column(name = "GROUP_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"groupid-gen")
#Id
#NotNull
#SequenceGenerator(name = "groupid-gen", sequenceName =
"GROUIP_ID_GENERATOR" )
private long groupId;
#OneToMany(mappedBy = "employeeDetail")
private List<EmployeeDetail> employeeDetails;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID", insertable=false ,
updatable=false)
private EmployeeDepartment employeeDepatment;
}
#Entity
#Table(name = "EMPLOYEE_DETAIL")
#IdClass(EmployeeID.class)
public class EmployeeDetail {
#ManyToOne
#JoinColumn(name = "GROUP_ID", insertable=false , updatable=false)
private EmployeeGroup employeeGroup;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"groupid-gen")
#SequenceGenerator(name = "groupid-gen", sequenceName =
"GROUIP_ID_GENERATOR" )
#Column(name = "GROUP_ID")
#Nonnull
private Long groupId;
#Id
#Nonnull
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
}
public class EmployeeId{
private Long groupId;
private Long employeeId;
public EmployeeId(final Long groupId, final Long employeeId) {
this.groupId = groupId;
this.employeeId = employeeId;
}
public EmployeeId() {
}
}
Expected result in these 3 tables should have proper values like.
Table EmployeeDepartment
DepartmentID GroupId
1 1
Table EmployeeGroup
GroupID
1
Table EmployeeDetail
GroupId EmployeeId
1 1
1 2
1 3
Actual results are below
Table EmployeeDepartment
DepartmentID GroupId
1 0
Table EmployeeGroup
GroupID
1
Table EmployeeDetail
GroupId EmployeeId
2 1
3 2
4 3
The important annotation is #MapsId("groupId")
Your mapping should be something like this:
#Entity
#Table(name="EMPLOYEE_DEPARTMENT")
public class EmployeeDepartment {
#Column(name = "DEPARTMENT_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"departmentid-gen")
#Id
#NotNull
#SequenceGenerator(name = "departmentid-gen", sequenceName =
"DEAPARTMENT_ID_GENERATOR" )
private long departmentId;
#OneToOne(mappedBy = "employeeGroup")
private EmployeeGroup employeeGroup;
#Column(name="GROUP_ID")
private long groupId;
#Entity
#Table(name="EMPLOYEE_GROUP")
public class EmployeeGroup {
#Column(name = "GROUP_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"groupid-gen")
#Id
#NotNull
#SequenceGenerator(name = "groupid-gen", sequenceName =
"GROUIP_ID_GENERATOR" )
private long groupId;
#OneToMany(mappedBy = "employeeDetail")
private List<EmployeeDetail> employeeDetails;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID", insertable=false, updatable=false)
private EmployeeDepartment employeeDepatment;
#Entity
#Table(name = "EMPLOYEE_DETAIL")
#IdClass(EmployeeID.class)
public class EmployeeDetail {
#MapsId("groupId")
#ManyToOne
#JoinColumn(name = "GROUP_ID", insertable=false , updatable=false)
private EmployeeGroup employeeGroup;
#Id
#Nonnull
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
#Entity
#Table(name="EMPLOYEE_DEPARTMENT")
public class EmployeeDepartment {
#Column(name = "DEPARTMENT_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"departmentid-gen")
#Id
#NotNull
#SequenceGenerator(name = "departmentid-gen", sequenceName =
"DEAPARTMENT_ID_GENERATOR" )
private Long departmentId;
#OneToOne(mappedBy = "employeeGroup")
private EmployeeGroup employeeGroup;
}
#Column(name="GROUP_ID")
private EmployeeGroup group;
#Entity
#Table(name="EMPLOYEE_GROUP")
public class EmployeeGroup {
#Column(name = "GROUP_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"groupid-gen")
#Id
#NotNull
#SequenceGenerator(name = "groupid-gen", sequenceName =
"GROUIP_ID_GENERATOR" )
private Long groupId;
#OneToMany(mappedBy = "employeeDetail")
private List<EmployeeDetail> employeeDetails;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID", insertable=false ,
updatable=false)
private EmployeeDepartment employeeDepatment;
}
#Entity
#Table(name = "EMPLOYEE_DETAIL")
#IdClass(EmployeeID.class)
public class EmployeeDetail {
#Id
#ManyToOne
#JoinColumn(name = "GROUP_ID", insertable=false , updatable=false)
private EmployeeGroup employeeGroup;
#Id
#Nonnull
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
You also need to change the EmployeeId accordingly:
public class EmployeeId{
private EmployeeGroup employeeGroup;
private Long employeeId;
public EmployeeId(final EmployeeGroup employeeGroup, final Long employeeId) {
this.employeeGroup= employeeGroup;
this.employeeId = employeeId;
}
However I haven't use composite keys this way before. If it doesn't work, then change EmployeeId to an embeddedId:
#Embeddable
public class EmployeeId implements Serializable{
#ManyToOne(fetch = FetchType.LAZY, optional = false)
private EmployeeGroup employeeGroup;
#Nonnull
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
public EmployeeId(final EmployeeGroup employeeGroup, final Long employeeId) {
this.employeeGroup= employeeGroup;
this.employeeId = employeeId;
}
#Entity
#Table(name = "EMPLOYEE_DETAIL")
public class EmployeeDetail {
#EmbeddedId
private EmployeeId id;
#ManyToOne
#JoinColumn(name = "GROUP_ID", insertable=false , updatable=false)
private EmployeeGroup employeeGroup;
}
If it still doesn't work, then please attach the code snippet where you create the entities.

Reuse a composite key for a child + a new field

I use spring boot, with jpa (hibernate) and postgresql
I use composite key.
#Entity
#IdClass(SamplingsPK.class)
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Samplings {
#Id
#GeneratedValue
private Integer id;
#Id
private int year;
#OneToMany(mappedBy = "sampling", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Samples> samples = new ArrayList<>();
...
}
public class SamplingsPK implements Serializable {
private Integer id;
private int year;
public SamplingsPK(Integer id, int year) {
this.id = id;
this.year=year;
}
private SamplingsPK(){
}
#PrePersist
public void prePersist() {
year = LocalDate.now().getYear();
}
}
#Entity
public class Samples {
#Id
#SequenceGenerator(name = "samples_id_seq", sequenceName = "samples_id_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "samples_id_seq")
private Integer id;
private String sampleLetter;
#ManyToOne
#JoinColumns({
#JoinColumn(name = "sampling_id", referencedColumnName = "id"),
#JoinColumn(name = "sampling_year", referencedColumnName = "year")
})
private Samplings sampling;
}
That work fine
Instead of having an sequence in samples, I would like to have a composite key... SamplingsPK + sampleLetter.
Is it possible to do it, how to save a sample?
This is a "derived identity", so Samples could be mapped with an #IdClass like this:
#Entity
#IdClass(SamplesPK.class)
public class Samples {
#Id
#ManyToOne
#JoinColumns({
#JoinColumn(name = "sampling_id", referencedColumnName = "id"),
#JoinColumn(name = "sampling_year", referencedColumnName = "year")
})
private Samplings sampling;
#Id
private String sampleLetter;
}
public class SamplesPK {
SamplingsPK sampling; // matches name of attribute and type of Samplings PK
String sampleLetter; // matches name and type of attribute
}
Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.

Jpa Auditing dont save data in table auditing

I have to implementes Auditing in my aplication.. i inserting this data correctly
but i want to save all atributter from my Entity ,
Exemple, name, epigrafe, .. and olthers.
I implemented the mothod but dosent work, just dont save the atributte..
lets see..
#Entity
#EntityListeners(AuditingEntityListener.class)
#Table(name = "logradouros_historico", schema = "aud")
public class LogradourosHistorico {
#Id
#GeneratedValue
private Long id;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "id_logradouro")
private Logradouros logradouro;
#CreatedBy
private String modificadoPor;
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
private Date modifiedDate = new Date();
#Enumerated(EnumType.STRING)
private Acoes acao;
#Column(name = "nome")
private String nome; //nome do logradouro
public LogradourosHistorico() {
super();
}
public LogradourosHistorico(Logradouros logradouro, String modificadoPor,
Acoes acao) {
super();
this.logradouro = logradouro;
this.modificadoPor = modificadoPor;
this.acao = acao;
}
//getters and setters
my class entityListner
public class LogradourosEntityListener {
#PostPersist
public void prePersist(Logradouros target) {
perform(target, Acoes.INSERTED);
}
#PreUpdate
public void preUpdate(Logradouros target) {
perform(target, Acoes.UPDATED);
}
#PreRemove
public void preRemove(Logradouros target) {
perform(target, Acoes.DELETED);
}
#Transactional()
private void perform(Logradouros target, Acoes acao) {
target.getNome();
EntityManager entityManager = BeanUtil.getBean(EntityManager.class);
entityManager.persist(new LogradourosHistorico(target, acao));
}
}
my class Logradouros
#Entity
#EntityListeners(LogradourosEntityListener.class)
#Table(name = "logradouros", schema = "glb", uniqueConstraints= #UniqueConstraint(columnNames={"id_entidade", "idLogradouro"}))
public class Logradouros extends Auditable<String> implements Serializable {
private static final long serialVersionUID = 3703309412387185484L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int idLogradouro;
#Column(name = "cep_geral")
private String cepGeral;
#Column(name = "epigrafe")
private String epigrafe;
#NotNull
#Column(name = "nome")
private String nome;
#Column(name = "nome_exibicao")
private String nomeExibicao;
#JoinColumn(name = "id_entidade")
#ManyToOne(/*cascade = CascadeType.ALL*/)
private Entidades entidade;
#NotNull
#JoinColumn(name = "id_municipio")
#ManyToOne(/*cascade = CascadeType.ALL*/)
private Municipios municipio;
// gettrs and settrs
so what i did wrong because i cant get the nome of entity Logradouros