Relationship mapping in Hibernate - java

I have a two table Company and CompanyRepo like below
COMAPNY
COMPANY_REPO
I have entities for those two tables like this :
#Entity
#Table(name="COMAPNY")
public class Company implements Serializable {
#Id
#Column(name="COMPANY_ID")
private Long companyId;
#Column
private String companyName;
#OneToMany(mappedBy="COMPANY")
private List<CompanyRepo> companyRepo;
}
#Entity
#Table(name="COMAPNY_REPO")
public class CompanyRepo implements Serializable {
#Id
#Column(name="COMPANY_REPO_ID")
private Long companyRepoId;
#Column
private String COMPANY_ID;
#Column
private String DEPT_ID;
#ManyToOne
#JoinColumn(name="COMPANY_ID")
private Company company;
}
Now i want to execute below query using a Hibernate relationship mapping
select Company_name from company as C ,company_repo as cr where c.company_id=cr.company_id and dept_id=10
I wrote a JPA repository like below by using a #OneToMany in Company table and #ManyToOne in CompanyRepo. But in resultant I am getting multiple COMPANYobject inside COMPANY_REPO Object.Does my relationship mapping is correct ?
public interface CompanyRepository extends JpaRepository<CompanyRepo, Long> {
public CompanyRepo findByDeptId(Long deptId);
}

Given your current database design, try something such as the following:
public interface CompanyRepository extends JpaRepository<Company, Long> {
#Query(value="SELECT * from company as C WHERE c.company_id = (SELECT cr.company_id FROM company_repo as cr WHERE cr.dept_id = ?1)", nativeQuery=true)
public Company findByDeptId(Long deptId);
}
The #Query annotation is a very powerful and flexible way to define methods in Repository interface. If you need more complex logic, I would recommend reading about the use and possibilities of the annotation. See here.

Based on your entity class your have multiple
COMPANY_ID that is not a proper way to declare your column name.
#Column
private String COMPANY_ID;
#ManyToOne
#JoinColumn(name="COMPANY_ID")
private Company company;
So please change your #Column
private String COMPANY_ID; to #Column("comp_id)
private String companyId;
If you want to get the CompanyRepo based on Company type then you need to change your query to fetch the dept id.
And your #Column
private String DEPT_ID; is String datatype so pass String to your repository.
#Query(" select companyRepo.company from CompanyRepo as companyRepo where companyRepo.DEPT_ID = :deptId")
public Company findByDeptId(String deptId);

Related

Create a new JPA Entity to produce a new object from two tables

Hello programming council, this is my first use of JPA in anger.
I have 2 Tables:
Entity
#Table(name="category")
public class Category {
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name="category")
private String category;
#Column(name="budget")
private double budget;
#Column(name="savings")
private String savings;
#Column(name="archive")
private String archive;
Entity
#Table(name="Transaction")
public class Transaction {
#Id
#Column(name="transaction_no")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private long transactionNo;
#Column(name="transaction_date")
private String transactionDate;
#Column(name="transaction_category")
private String transactionCategory;
#Column(name="transaction_description")
private String transactionDescription;
#Column(name="transaction_amount")
private double transcationAmount;
#Column(name="transaction_auto")
private String transactionAuto;
I want to create a new object called Tile which will contain String category and String balance, the SQL for which would be:
select t.transaction_category as category, sum(t.transaction_amount) as balance
from budgeteer.category c
join budgeteer.transaction t
on c.category = t.transaction_category
group by t.transaction_category;
What is the easiest/best way for me to accomplish this?
Thanks in advance.
Ok, so after a little more research, I discovered that I could actually just do this with the same Entity, repository and service without generating a table. You just need to leave out the #Table annotation when you create your entity.

Spring Data JPA - ManyToMany - JPQL - #Query formation in Repository

I have a spring boot project with PostgreSQL RDBMS.
I have #ManyToMany relation between two entities - Customer & Product. They are joined by the customer_product. But while forming JPQL at repository layer, I am facing difficulties. Here is entity:
#Entity
#NamedQuery(name="Customer.findAll", query="SELECT c FROM Customer c")
public class Customer implements Serializable {
... all properties ... getter setter constructor...
//bi-directional many-to-many association to Product
#JsonIgnore
#ManyToMany
#JoinTable(
name="customer_product"
, joinColumns={
#JoinColumn(name="customer_id")
}
, inverseJoinColumns={
#JoinColumn(name="product_id")
}
)
private List<Product> products;
#Entity
#NamedQuery(name="Product.findAll", query="SELECT p FROM Product p")
public class Product implements Serializable {
... all properties ... getter setter ... constructors ...
//bi-directional many-to-many association to Customer
#JsonIgnore
#ManyToMany(mappedBy="products")
private List<Customer> customers;
Now at the repository later:
#Repository
public interface CustomerRepository extends CrudRepository<Customer, Integer> {
//Below mentioned query works perfectly as Customer & Address has OneToMany Relation
#Query("select new com.arindam.springjpa.springdatajpaexamples.vo.CustomerDetailsVO(c.id, c.customerName, a.fullAddress) from Customer c, Address a where c.address.addressId=a.addressId")
List<CustomerDetailsVO> findAllCustomerDetails();
// But I need help on below query
// I want to find out full details of ManyToMany relation between customer & product
#Query("select new com.arindam.springjpa.springdatajpaexamples.vo.CustomerProductAddressDetailsVO(c.id, c.customerName, a.fullAddress, p.productName) from Customer c, Address a, Product p where c.address.addressId=a.addressId and c.products.product.productId=p.productId")
List<CustomerProductAddressDetailsVO> findAllCustomerAddressProductDetails();
To have results in VO here is simple VO class
#Entity
public class CustomerProductAddressDetailsVO {
private Integer id;
private String customerName;
private String fullAddress;
private String productName;
//Like a simple POJO with getter setter constructors
Can you please suggest.
Thanks for your valuable feedback.
I have resolved the issue. Since the entity classes have been generated using Eclipse plugins, so the class for customer_product was not been generated. So I manually generated it and used the query. So the final code is:
#Entity
#Table(name="customer_product")
#NamedQuery(name="CustomerProduct.findAll", query="SELECT c FROM CustomerProduct c")
public class CustomerProduct implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Integer id;
#Column(name="customer_id")
private Integer customerId;
#Column(name="product_id")
private Integer productId;
and Repository layer:
#Query("select new com.arindam.springjpa.springdatajpaexamples.vo.CustomerProductAddressDetailsVO(cp.id, c.customerName, a.fullAddress, p.productName) from Customer c, Address a, Product p, CustomerProduct cp "
+ "where c.address.addressId=a.addressId and cp.productId=p.productId and cp.customerId=c.id")
List<CustomerProductAddressDetailsVO> findAllCustomerAddressProductDetails();
It works perfectly.

HQL strategy to equal embedded entities

i'm curious about how HQL would assert equality between an entity instances.
Let's say I have a Entity called Person
#Entity
public class Person{
#Id
private Long id;
private String name;
}
and Department
#Entity
public class Department {
#Id
private Long id;
#ManyToOne
private Person person;
}
then it's fine if I do the following statement:
Query query = getSession().createQuery("from Department d where d.person = ?");
query.setProperty(0,new Person(1L));
but, what if I have an Embedded entity and no pk defined? like
#Embeddable
public class Adress {
private String email;
private String street;
private Long identifier;
}
#Entity
public class Person{
#Id
private Long id;
private String name;
#Embedded
private Address address;
}
would have any way so I could tell JPA to make it work:
Query query = getSession().createQuery("from Person p where p.address = ?");
query.setProperty(0,new Address(1L));
even though it's not exactly a primary key?
For sure i know i'd work if I tried p.adress.identifier, and then passed just the Long value, but the point is, can I tell JPA provider how it's gonna kind of 'implement' equality my way?
Thank you all
No, it is not supported and it would be difficult in general or would not make sense in some situations, like when there are collections in the Embeddable.
If you find that you need this often though, consider converting such Embeddables to custom user types. Then you can perform comparisons the way you described.

Joining two table in spring data JPA and Querying two table data from repository

I am using Sprind JPA, Spring 3.1.2(in future 3.2.3), Hibernate 4.1 final.
I am new to Sprind Data JPA. I have tow Table Release_date_type and Cache_media which entities are as follows :
ReleaseAirDate.java
#Entity
#Table(name = "Release_date_type")
public class ReleaseDateType {
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
private Integer release_date_type_id;
#Column
private Integer sort_order;
#Column
private String description;
#Column
private String data_source_type;
#Column(nullable = true)
private Integer media_Id;
#Column
private String source_system; with getters and setters..
and CacheMedia as
#Entity
#Table(name = "Cache_Media")
public class CacheMedia {
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
private Integer id;
#Column(name="code")
private String code;
#Column(name="POSITION")
private Integer position;
#Column(name="DESCRIPTION")
private String media_Description; with setter and getters.
Now my repository interface is as follows :
public interface ReleaseDateTypeRepository extends CrudRepository<ReleaseDateType, Long>{ }
Now i want to write a method(Query) in ReleaseDateTypeRepository interface which can get all the data from Release_Date_Type table including appropriate media_description from Table 'Cache_Media' based on media_id of Release_date_type table.
So my select (SQL)query looks like
SELECT * from Release_Date_Type r left join Cache_Media c on r.media_id=c.id
I don't know how to map entities.
I tried so many thing but not luck.
Any help is appreciated.
Its not the answer for joining via Hibernate, but alternatively you can create a view with your join and map the view to your objects

How to get child table rows using parent table ID?

I have two tables: Organization(Parent) and Department(Child).
There is One to Many relationship, and is mentioned in Organization table only.
#Entity
#Table(name="TBL_STD_ORGANIZATION")
public class Organization implements Serializable {
#Id
#GeneratedValue
#Column(name="FLD_ORG_ID")
private Long organizationId;
#Column(name="FLD_ORG_NAME")
private String orgName;
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private java.util.List<Department> listOfDepartMents = new java.util.ArrayList<Department>();
}
Below is Department Class:
#Entity
#Table(name="TBL_STD_DEPARTMENT")
public class Department implements Serializable {
#Id
#GeneratedValue
#Column(name = "FLD_DEPARTMENT_ID")
private Long departmentId;
#Column(name = "FLD_DEPARTMENT_NAME")
private String departmentName;
}
I wrote relationship in Parent table, because of it hibernate creates third table.
Now, I have to retrieve departments start with "sa" keyword and in specific organization.
So I want the HQL or SQL query query. I am not getting it how to write such complex query.
Any suggestions?
I'm fairly certain the HQL/JPQL would be:
SELECT d FROM Organization o JOIN o.listOfDepartMents d WHERE d.departmentName LIKE "sa%"

Categories