I'm using the following SQL to join employees, user_projects and project_master
SELECT DISTINCT usr.user_number,
emp.emp_name
FROM employees emp
LEFT JOIN user_projects usr
ON (emp.user_number = usr.user_number)
JOIN project_master mast
ON (usr.project_id = mast.project_id)
WHERE mast.active = 'Y'
AND emp.user_number = 'SMITH'
In Employee entity, I have the following JPQL defined as namedQuery
#NamedQuery(name = "Employee.findProjects", query = " select DISTINCT u.userNumber,e.empName" +
" from Employee e LEFT JOIN e.userProjectsList u where e.userNumber='SMITH' ")
Not sure how to link UserProjects and ProjectMaster to create a where condition
mast.active = 'Y' in Employee entity's findProjects namedQuery
How to join UserProjects and ProjectMaster in Employee Entity class?
Entities
Entity Employee
#Table(name = "EMPLOYEES")
public class Employee implements Serializable {
#Id
#Column(name = "USER_NUMBER", nullable = false)
private String userNumber;
#Column(name = "EMP_NAME")
private String empName;
#OneToMany(mappedBy = "employee")
private List<UserProjects> userProjectsList;
Entity UserProjects
#Table(name = "USER_PROJECTS")
public class UserProjects implements Serializable {
#Id
#Column(name="PROJECT_ID", nullable = false, insertable = false,
updatable = false)
private String projectId;
#Id
#Column(name="USER_NUMBER", nullable = false, insertable = false, updatable = false)
private String userNumber;
#ManyToOne
#JoinColumn(name = "PROJECT_ID", referencedColumnName = "PROJECT_ID")
private ProjectMaster projectMaster;
Entity ProjectMaster
#Table(name = "PROJECTMASTER")
public class ProjectMaster implements Serializable {
#Id
#Column(name="PROJECT_ID", nullable = false)
private String projectId;
#Column(name="PROJECT_DESCRIPTION")
private String projectDesc;
#Column(name="ACTIVE")
private String active;
select DISTINCT u.userNumber,e.empName from Employee e LEFT JOIN
e.userProjectsList u JOIN u.projectMaster pm
where e.userNumber='SMITH' AND pm.active='Y'
Isn't this work?
Related
I have two entities: TableA and TableB. When I fetch TableA, TableB is always null. What am I doing wrong?
This is how I am getting it:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<TableA> criteriaQuery = builder.createQuery(TableA.class);
Root<TableA> from = criteriaQuery.from(TableA.class);
criteriaQuery.select(from);
This is the Query made:
select generatedAlias0 from TableA as generatedAlias0
TableA:
#Entity
#Table(name = "TableA")
public class TableA implements Serializable {
#Id
#Column(name = "id", nullable = false)
private Integer id = null;
#Id
#Column(name = "active", nullable = false)
private Integer active = null;
private Integer parentId = null;
private String myColA = null;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumns({
#JoinColumn(name = "id", referencedColumnName = "parentId"),
#JoinColumn(name = "active", referencedColumnName = "active")}
)
#Where(clause = "active=1")
private TableB TableB = null;
private Boolean ignorePlanCutoff = null;
}
TableB:
#Entity
#Table(name = "TableB")
public class TableB implements Serializable {
#Id
#Column(name = "id", nullable = false)
private Integer id = null;
#Id
#Column(name = "active", nullable = false)
private Integer active = null;
private Integer parentId = null;
private Boolean colB = null;
}
Both these entities have composite IDs, not showing that here for brevity.
I'm newbie
I'm trying pass this Postgres query to JPA/JPQL
SELECT
DISTINCT(srv.code) AS Serv_Cod,
srv.id AS Serv_id,
srv.description AS Serv_Desc
FROM db.Category AS cat
join db.Classification AS cla ON cat.id = cla.cat_id
join db.Service AS srv ON srv.id = cla.srv_id
WHERE cat.id = 10
ORDER BY srv.id;
Now I want to write the same Query, I have the Entities with the same name Table.
Classification
#Entity
#Table(name = "Classification", schema = "db")
#Audited
public class Classification implements Identifiable<Long> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "srv_id", nullable = true)
private Service service;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "cat_id", nullable = true)
private Category category;
....
}
Service
#Entity
#Table(name = "Service", schema = "db")
#Audited
public class Service implements Identifiable<Long> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "code", nullable = false)
private String code;
#Column(name = "description", nullable = false)
private String description;
....
}
I was reading, but I'm very confused...
I don't know how to write the ON for the JOIN, and establish the DISTINCT for a Column/Field.
Long myID = 25L;
this.em.createQuery("SELECT NEW SomeDto(srv.id, srv.code, srv.description)"
+ " FROM Classification cla"
+ "JOIN cla·cat_id cat"
+ "JOIN cla·srv_id srv"
+ "WHERE cat.id = :id"
,BaseObjectDto.class).setParameter("id", myID).getResultList();
Thank you for you valuable Help.
The query is very simple. When you have ToOne relationships you can navigate to the related entity. There is no need to JOIN ON.
Even with ToMany there is no need for the ON because this is already defined in the mapping.
So the query will look like:
SELECT NEW SomeDto(cla.service.id, cla.service.code, cla.service.description)
FROM Classification cla
WHERE category.id = :id
I created a left join query with JPQL in spring data jpa but failed in my unit test. There are two entities in the project.
Product entity:
#Entity
#Table(name = "t_goods")
public class Product implements Serializable {
#Id
#GeneratedValue
#Column(name = "id", length = 6, nullable = false)
private Integer id;
#Column(name = "name", length = 20, nullable = false)
private String name;
#Column(name = "description")
private String desc;
#Column(name = "category", length = 20, nullable = false)
private String category;
#Column(name = "price", nullable = false)
private double price;
#Column(name = "is_onSale", nullable = false)
private Integer onSale;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "brand_id")
private Brand brand;
// getter and setter
}
Brand entity:
#Entity
#Table(name = "tdb_goods_brand")
public class Brand implements Serializable {
#Id
#GeneratedValue
#Column(name = "id", length = 6, nullable = false)
private Integer id;
#Column(name = "brand_name", unique = true, nullable = false)
private String name;
#OneToMany(mappedBy = "brand", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Product> products;
// getter and setter
}
And a third class Prod to map the query results to Object:
public class Prod implements Serializable {
private Integer id;
private String name;
private double price;
//private String brandName;
// getter and setter
}
It works fine with this query:
public interface ProductRepository extends JpaRepository<Product, Integer> {
#Query(value = "select new com.pechen.domain.Prod(p.id, p.name, p.price) from Product p ")
Page<Prod> pageForProd(Pageable pageRequest);
}
But if I add new property brandName for Prod and refactor the query with left join, it test fails:
#Query(value = "select new com.pechen.domain.Prod(p.id, p.name, p.price, b.name) from Product p left join com.pechen.domain.Brand b on p.brand_id = b.id")
Page<Prod> pageForProd(Pageable pageRequest);
The problem seems to be here on p.brand_id = b.id because there is not a brand_id property in Product, it's just a column name. So how can I make this work?
Update:
There turned to be some sytax errors in the JPQL query, just fix it as the following:
#Query(value = "select new com.pechen.domain.Prod(p.id, p.name, p.price, b.name) from Product p left join p.brand b")
Page<Prod> pageForProd(Pageable pageRequest);
Besides, it's very troublesome in this way to create another class everytime to map the query results into object(I mean the Prod class). So is there a good way to work with it? Any help would be appreciated.
Instead of p.brand_id = b.id you should do p.brand.id = b.id
i am trying to extract a list of objects from database from entity (table) StudySeries:
#Entity
#Table(name="StudySeries", uniqueConstraints = {
#UniqueConstraint(columnNames = "SeriesInstanceUID")})
public class StudySeries implements Serializable {
...
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "SeId", unique = true, nullable = false)
private Long seId;
#Column(name="SeriesInstanceUID", unique=true, nullable = false)
private String seriesInstanceUID;
...
#ManyToOne
#JoinColumn(name = "StId", referencedColumnName="StId")
private StudyDetails studyDetails;
...
}
This entity is N-1 joined with StudyDetails (on StudyDetails has many StudySeries):
#Entity
#Table(name="StudyDetails", uniqueConstraints = #UniqueConstraint(columnNames = "StudyInstanceUID"))
public class StudyDetails implements Serializable {
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name="StId", unique = true, nullable = false)
private Long stId;
#Column(name="StudyInstanceUID", unique=true, nullable = false)
private String studyInstanceUID;
...
#OneToMany(fetch = FetchType.LAZY, mappedBy = "studyDetails", cascade = CascadeType.ALL)
private Set<StudySeries> studySeries = new HashSet<StudySeries>(0);
...
}
In my StudySeriesDAOImpl() i am trying to:
#Override
public List<StudySeries> getStudySeriesObjectsByStudyId(Long stId) {
List<StudySeries> results=new ArrayList<>();
Session s=HibernateUtil.openSession();
s.beginTransaction();
String hql = "from StudySeries E where E.studyDetails.stId = stId";
Query query = s.createQuery(hql);
query.setParameter("stId", stId);
results = query.list();
s.getTransaction().commit();
s.close();
log.info(">>>>> list size: " + results.size());
return results;
}
I have also tried the hql query as:
String hql = "from StudySeries E where E.stId = stId";
However i am getting:
org.hibernate.QueryParameterException: could not locate named parameter [stId]
at org.hibernate.engine.query.spi.ParameterMetadata.getNamedParameterDescriptor(ParameterMetadata.java:100) at org.hibernate.engine.query.spi.ParameterMetadata.getNamedParameterDescriptor(ParameterMetadata.java:100)
at org.hibernate.engine.query.spi.ParameterMetadata.getNamedParameterExpectedType(ParameterMetadata.java:106)
at org.hibernate.internal.AbstractQueryImpl.determineType(AbstractQueryImpl.java:466)
at org.hibernate.internal.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:436)
at com.npap.dao.StudySeriesDAOImpl.getStudySeriesObjectsByStudyId(StudySeriesDAOImpl.java:239)
Any ideas what is wrong?
In the StudySeries class, the id is named as 'seId', not 'stId'.
You should do like this: String hql = "from StudySeries E where E.seId = stId";
I am struggling with Hibernate Criteria. My aim is to create the following request using Hibernate Criteria :
select
count(*) as y0_
from
PInterface this_
inner join
Product product2_
on this_.product_id=product2_.id
where
this_.product_interface_type_id=?
Here is my code:
#Entity #Table(name = "PInterface")
public class PInterface {
#Id
#GeneratedValue
#Column(name = "id", nullable = false, insertable = false, updatable = false)
private int id;
#Column(name = "product_id")
private int productId;
#Column(name = "product_interface_type_id")
private int type;
#ManyToOne(optional=false)
#JoinColumn(name = "product_id", referencedColumnName = "id", insertable=false, updatable=false)
private Product product;
}
#Entity #Table(name = "Product")
public class Product {
#Id
#GeneratedValue
#Column(name = "id", nullable = false, insertable = false, updatable = false)
private int id;
private String name;
}
//Criteria is :
Object criteria = sessionFactory.getCurrentSession()
.createCriteria(PInterface.class)
.add(Restrictions.eq("type", 1))
.setProjection(Projections.rowCount())
.uniqueResult()
;
However, the results ...
select
count(*) as y0_
from
PInterface this_
where
this_.product_interface_type_id=?
Where Inner join?
Thank you for help!
How about this:
Object criteria = sessionFactory.getCurrentSession()
.createCriteria(PInterface.class)
.createCriteria("product")
.createAlias("product", "p")
.add( Restrictions.eqProperty("p.id", "productId") )
.add(Restrictions.eq("type", 1))
.setProjection(Projections.rowCount())
.uniqueResult();