How can ı get just specific variables in spring? - rest

For example, when I want to get properties of them but not all of them. For example, when I use findAll(); function - it displays everything but I wanna for example just id and name there is any special function or anything for doing this?
Think that ı have an entity class like that.
#Id
private int api_id;
#Column(name = "id")
private int id;
#Column(name = "name")
private String name;
#Column(name = "city")
private String city;
#Column(name = "founded_at")
private int founded_at; //I declare as a integer because the variable consists of 4 integers.
#Column(name = "web_page")
private String web_page;

You can use spring-data's interface based projections to select particular fields from DB:
interface NameAndIdOnly {
int getId();
String getName();
}
and in your repository:
...
List<NameAndIdOnly> findAllWithNameAndId();
...
This will do select id, name from <table>.
Please read Projections for more info.

Related

Creating a query with a one-to-one relationship

I have two tables...a loan table and a customer table. A customer can make multiple loans but I would like to restrict the customer to one active loan at a time. They cannot create a second loan until the first loan is finished (loan.active=false)
I have set up my loan table like this :
#Entity
public class Loan implements Serializable {
private static final long serialVersionUID = 0x62B6DA99AA12AAA8L;
#Column #GeneratedValue(strategy = GenerationType.AUTO) #Id private Integer id;
#OneToOne(fetch = FetchType.LAZY)
private Customer customer;
#Column private String dateLoaned;
#Column private String dateToReturn;
#Column private String dateOfReturn;
#Column private Boolean active=false;
And the customer table like this :
#Entity
public class Customer implements Serializable {
private static final long serialVersionUID = 0x63A6DA99BC12A8A8L;
#Column #GeneratedValue(strategy = GenerationType.AUTO) #Id private Integer id;
#Column private String firstname;
#Column private String surname;
#Column private String address;
#Column private String town;
#Column private String postcode;
#Column (unique=true) private String personalnumber;
#Column (unique=true) private String emailaddress;
#OneToOne(fetch = FetchType.EAGER)
private Loan loan;
This allows me to create a new loan with the same customer. So far so good.
I would like to make a query that allows me to find if a customer already has an active loan.
My loan repository so far is :
#Query("select loan_id from Loan l where l.customer.id = :customerId and l.active = true")
Boolean customerHasActiveLoan(#Param("customerId") Integer customerId);
Is this the correct way to do this?
In spring-data-jpa you can both have #Query or write a method that generates a query. There is nothing wrong to have #Query but because your repository method is quite simple you can use also method name only
For the example the equivalent of:
//Will return the active loan, if exists, or null
#Query("select l from Loan l where l.customer.id = :customerId and l.active = true")
public Loan getActiveLoad(#Param("customerId") Integer customerId)
could be simplified as
public Local findOneByCustomerIdAndActiveIsTrue(Long id)
Sometimes method name approach can generate long method name, and for this reason, if you prefer, you can use #Query annotation

Query in Spring JPA using List of two parameters

public interface InventoryRepository extends JPARepository<Inventory, Long> {
List<Inventory> findByIdIn(List<Long> ids);
}
Above is working fine, however in same way I am trying to fetch the List or Map, based on multiple params List ids and List sortNumber.
I would be also happy with return type Map from the method.
I came up with below things, which isn't correct.
List<Inventory> findByIdANDSortNumberIn(List<Long> ids, List<Long> sortNumbers);
Should do it with help of Criteria ? Is there any better way to do it?
Entity :
#Entity
#Table(name = Constants.T_INVENTROTY)
#Data
public class Inventory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = Constants.COLUMN_IN_DM)
private Long id;
#Column(name = Constants.COLUMN_PROD_DESCRIPTION)
private String prodDescription;
#Column(name = Constants.COLUMN_PROD_DESCRIPTION)
private Long sortNumber;
#Column(name = Constants.COLUMN_QUANTITY)
private long quantity
}
This should work
List<Inventory> findByIdInAndSortNumberIn(List<Long> ids, List<Long> sortNumbers);
You can specify And and do the same for multiple fields.

Spring projections select collection

I am attempting to have a station projection include a list of associated logos. Below is my domain:
#Table(name = "Station")
public class Station implements Serializable {
#Id
#Column(name = "Id")
private int id;
#OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
mappedBy = "station")
private Set<Logo> logos;
}
The #OneToMany associated logos:
#Table(name = "Logo")
public class Logo {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Transient
private String fullUrl; // calculated
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "StationId", nullable = false)
private Station station;
}
My repository and query is as follows:
#Query(value = "SELECT s.id AS Id, s.logos As Logos FROM Station s JOIN s.users su WHERE su.username = ?1")
Collection<StationListViewProjection> findStationsByUsername(String username);
My station projection expects the Id and a list of logoProjections
#Projection(name = "StationListViewProjection", types = Station.class)
public interface StationListViewProjection {
int getId();
Set<LogoProjection> getLogos();
}
The logoProjection only needs the url
#Projection(name = "LogoProjection", types = Logo.class)
public interface LogoProjection {
String getFullUrl();
}
When i execute my query I get a strange response:
MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as col_5_0_, . as col_6_0_, stationlog3_.id as id1_20_0_'
If I understand this
#Transient
private String fullUrl; // calculated
correct, your fullUrl gets calculated inside your java code and more important, it doesn't have a matching column in the database. You can't use such field in projections directly. You might be able to use an Open Projection and specify the calculation to obtain the fullUrl using a #Value annotation.

JPA is not creating TIME part of TIMESTAMP

I have an entity like below
#Entity
#Table(name="PRODUCTS")
public class Feed implements Serializable{
private static final long serialVersionUID = -1732936132016478456L;
#Id
#GeneratedValue( strategy = GenerationType.AUTO)
#Column(name = "ID")
private int id;
#Column(name = "IMAGE_PATH")
private String imagePath;
#Column(name = "DESCRIPTION")
private String description;
#ManyToOne
#JoinColumn(name="UPLOADER", nullable = false)
private User uploader;
#Column(name = "TAGS")
private String tags;
#Column(name = "DATE", columnDefinition="")
private Date date;
#Column(name = "LINK")
private String link;
}
I'm using below code to create entity
#Transactional
#Override
public Feed createFeed(Feed feed) {
this.entityManager.persist(feed);
this.entityManager.flush();
}
Everything is working perfectly but DATE column which is of type timestamp and set to CURRENT_TIMESTAMP as default is only populating Date part not time part.
I tried firing manual query and that populated timestamp properly.
Am I missing anything there?
If the Date is of type java.sql.Date JPA will only store the Date part in the database field.
If it's java.util.Date you must add #Temporal(TemporalType.TIMESTAMP) to also store the time part.
The TemporalType defines the precision of the date.
https://docs.oracle.com/javaee/6/api/javax/persistence/TemporalType.html
I got the solution.
I still don't know the reason and that is why i am not marking this as answer.
I annotated my date variable with #Temporal(TemporalType.DATE) and just that did the trick.
One thing to note: I had used java.util.Date

how to access to subproperties with jpa metamodel in where clause

I have a two entities with relation between they are.
public class Client implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Integer id;
#NotNull
#Size(min = 3, max = 25)
private String firstName;
#NotNull
#Size(min = 3, max = 25)
private String lastName;
private String login;
private String password;
#OneToMany(mappedBy = "client")
private List<Project> projects;
}
and
public class Project implements Serializable {
private static final long serialVersionUID = 4762714047114442539L;
#Id
#GeneratedValue
private Integer id;
private String name;
#Temporal(TemporalType.TIMESTAMP)
private Date startDate;
#ManyToOne
#JoinColumn
private Client client;
}
I want to made a query using jpametamodel and Criteria API. Like this:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Project> q = cb.createQuery(Project.class);
Root<Project> projects = q.from(Project.class);
q.where(cb.equal(projects.get(Project_.client), clientId));
Problem for me that i don't know how to get access to "id" property of Client in this string:
q.where(cb.equal(projects.get(Project_.client), clientId));
i want to get something like
q.where(cb.equal(projects.get("client.id"), clientId));
but with jpametamodel. It is possible? :)
Tried something like this?
projects.get(Project_.client).get(Client_.id);