How do I store integer type list in a comma-separated format in Hibernate?
For example - I have a city table where I have cityId and CityName. In another table I have employee details.An employee can be tagged with multiple city.
I have created another table for employee-city mapping where I want to store the cities in comma separated format.
Table- Employee
----------------------------
Employee_ID Employee_Name
1 Employee 1
2 Employee 2
Table -city
------------------------
City_ID City_Name
1 City_1
2 City_2
Table- Employee-City Mapping
-----------------------
Emp_ID City_id
1 1,2
2 1,2
How to do the this kind actions in Hibernate ? Please help. I am using MySQL as the database backend.
It looks like you are trying to represent a one-to-many relationship.
The conventional SQL way to represent a one-to-many relationship is via multiple rows in a join table. In your case the join table is the employee-city table with a modified design with multiple rows per city rather than multi-valued columns:
Table- Employee-City Mapping
-----------------------
Emp_ID City_id
1 1
1 2
2 1
2 2
JPA (which Hibernate supports) has direct support for mapping these relationships to Collection fields. Your Employee class would have a cities field with type List<City> annotated with #OneToMany.
#Entity
public class Employee {
#Id
#Column(name="Emp_ID")
private long id;
#OneToMany
#JoinColumn(name="Emp_ID", referencedColumnName="City_ID")
private List<City> cities;
// ... rest of the class: constructor, getters, setters
}
The following guide may also help:
https://en.wikibooks.org/wiki/Java_Persistence/OneToMany
Related
I have 2 tables in MySQL database: user and user_additional_details with columns described below.
User
id (auto increment)
userId (unique)
first name
last name
phone
email
User Additional Details
id (auto increment)
userId (matches userId in User)
personalPhone
personalEmail
Table user_additional_details contains 0 or 1 row for each userId in user table.
However, database does not have a foreign key constraint defined. Ideally, columns from user_additional_details should have been added as nullable columns in user table, but that was not done for some unknown reason. Now I need to define the entity for following query.
select user.userId, user.phone, user_a_d.personalPhone
from user
join user_additional_details as user_a_d
on user.userId = user_additional_details.userId
I tried defining JPA entities for the tables, but not able to figure out how to create an entity that uses columns from different tables.
It seems like the SecondaryTable annotation is what you are looking for
Specifies a secondary table for the annotated entity class. Specifying
one or more secondary tables indicates that the data for the entity
class is stored across multiple tables.
Here you find a detailed example of how to use it - http://www.thejavageek.com/2014/09/18/jpa-secondarytable-annotation-example/
Create UserEntity (with all the columns from User table) and UserAdditionalDetailsEntity(with all the columns from user_additional_details table). I assume you are aware how to create JPA entities and map them to database table.
I hope you would have create entity manager factory object in your spring configuration file. With the help of that create entity manager object .
Once EntutyManager Object is created:
Query q= em.createQuery("select user.userId, user.phone, userDetails.personalPhone
from UserEntity user
join UserAdditionalDetailsEntity as userDetails
on user.userId = userDetails.userId");
List<Object[]> resultList= q.getResultList();
Once you get resultList you can iterate over the list of object array and get data.
Each index of the resultList will contain the object array representing one row
Keep in mind that field name mentioned in query should be same as the one mentioned in your JPA Entites.
I have two tables employee and bankname. In employee table there is a column bank_name_id which refers the column of bank table.
I have mapped employee bank_name_id with bank bank_name_id with many to one
I'm using spring mvc #RestController while returning it correctly fetch the data from bankname but converting into json its have repeated fetched data
Table 1 Employee Table:
empid empname bank_name_id
1 XXX 1
Table 2 Bankname table
bank_name_id bank_name
1 QQQ
JSON output:
{
empid:1,
empname:"xxx",
bank:{bank_name_id:1,bank_name:QQQ},
bankname:{bank_name_id:1,bank_name:QQQ}
}
this bankname data is repeated
As per you result it show that you have two variables in emp entity one bank and other bankname so please delete bankname variable from emp entity. and then check otherwise share you code here.
A person's address may look as the following:
country: USA
state: Some state
city: N.Y.
Street: some stree name with buildings
Building: number of the building on the street
Or as an alternative if building consists of several apartments/rooms another entity should be used:
Apartments/rooms: number of the apartment in the building
every next level in the example has the parent one as a foreing key that cannot be null:
county - is a container of states
state - is a container of cities and so one.
building - may be or may be not a container of rooms/apartments.
As a result I have the following tables for each level:
country
id name
1 USA
state
id country_id name
2 1 N.Y.
city
id state_id name
3 2 New York
Street
id city_id name
4 3 Some Street Name
Building
id street_id number
5 4 28
apartment
id building_id number
8 5 36
The problem I've met is how to map person to this tables structure?
Person may or may not live in an apartment, if it's a big family house for instance.
Ideally I'd like to have a collection of some entities:
ManyToMany
Collection<SomeEntity> addresses ...
where SomeEntity can refer either to an apartment or to a building directly.
Here are options I'm considering now, but I don't like them.
The first option where SomeEntity will have a type - either building or apartment and it will look like:
SomeEntity
id person_id type address_id
10 11 building 21
11 13 apartment 24
where in the first case it address_id refers to the building table, in the second one - to the apartment table.
The second option is to have a table that have the following list of fields:
SomeEntity
id person_id country_id state_id city_id street_id building_id apartment_id
In this case, if a bulding has no rooms, the apartment_id field is null. Also it's useful if I need for example to get list of persons who live in the city/or on the street cause I don't need to join all address-related tables, just refer to SomeEntity table. What do you think about this table? How to map the Person object in this case? SomeEntity - is just a table, not the object. My services actually should not know anything about internal tables structure. This issue is not clear to me. Probably you can offer the better solution.
Please, help.
if something similar to my comment is your solution then what you asked is how to map join in hibernate.
it will be something like this :
#Entity
#Table(name = "TEST_TABLE_A")
public class TestTableA {
public TestTableA(){
}
public TestTableA(String aName){
this.aName = aName;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "A_ID")
private Long id;
#Column(name = "A_NAME")
private String aName;
//some other atribut here
#ManyToMany(cascade = CascadeType.REFRESH)
#JoinTable(name="A_JOIN_B",
joinColumns={#JoinColumn(name="A_ID")},
inverseJoinColumns={#JoinColumn(name="B_ID")})
private Set<TestTableB> testJoins = new HashSet<TestTableB>();
//Getters and setters of all the collumn here
}
you can assume the TEST_TABLE_A is your BUILDING table in your database, and TestTableB is your apartment entity. and A_JOIN_B is your SOME_ENTITY table, and testJoins is the object you are looking for. You must get that object from the Building through.
You may want to change the relationship to #OneToMany if you want. and change the Cascade.Type (detail about cascade) so it will be easier for you to maintain that table.
I would like to write a JPA entity class that has a one to many relationship. I would like to avoid defining the relationship in the parent class to avoid the data to be loaded every time a reference is made for the object even when there is no need for the associated data. I have read that even with Lazy loading, the data can be loaded so i need to avoid that.
In the following example,
Customer table
------------------------
customerid, customerName
1 John
2 Bob
Order Table - customerId is a foreign key to Customer
orderId, customerId, orderDate
1 1 12MAY2012
1 1 13MAY2012
1 2 16MAY2012
JPA Entities
#Entity
public class Customer {
// all Customer-related fields WITHOUT #OneToMany relationship with Order
}
#Entity
public class Order {
String orderDate;
#ManyToOne
private Customer owner;
}
How would i retrieve data from the customer table based on a condition on the order table? For example, how can i say "Get me all customers who have made an order where the orderDate is between two dates?
using hbm.xml there are query only properties to achieve what you want
http://ayende.com/blog/4054/nhibernate-query-only-properties
Imagine a table emp:
CREATE TABLE emp
( id NUMBER
, name VARCHAR
, dept_code VARCHAR
)
and a table dept:
CREATE TABLE dept
( code VARCHAR
, name VARCHAR
)
emp.dept_code references dept.code as a ForeignKey.
These tables are mapped to JPA Entities, and the ForeignKey is modeled as an association:
#ManyToOne
#JoinColumn(name = "dept_code")
private Department department;
Given following data:
emp dept
---------------- ------------------
1 John SALS SALS Sales
2 Louis SALS SUPT Support
3 Jack SUPT
4 Lucy SUPT
I would like to write a JPA query that returns all Emloyees in the Support Department. Assume I know the PrimaryKey of the Support Department (SUPT)
I guess that would be:
SELECT emp
FROM Employee emp JOIN emp.department dept
WHERE dept.code = 'SUPT'
Question:
As the Department key SUPT code is available in the emp table, is there a way to rewrite the JPA query by avoiding the JOIN to the Department Entity?
Would this result in a performance improvement? Or is a JPA implementation (like Hibernate) smart enough to avoid the database join to the dept table?
You would usually write the query as
select emp
from employee emp
where emp.department.code = 'SUPT'
and let your provider figure out the best way to come up with the result. In the case of hibernate, yes, it is smart enough to realize it can just look at the join column.
edit : It is worth noting, that you haven't set up lazy loading in your annotations, so it's going to join the table in to create the department entity anyway :)