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
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
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.
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.
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
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);