Hibernate help me write query - java

Im making an email client in java. When user creates mail with attachment(document), it saves all the data about email message in database but in multiple tables, like attachement title in Document_table.title, number of message in msgnumber.num, date in msgnumber.date, name of sender in Official_Person.name and OfficialPerson.secondname.
How do i retrieve all this data and display it (im using Jtable for this)? I know how to get data if it saved in one table but not multiple. please help me.
one format has many documnets.
DOCUMENT:
#Entity
#Table(name="DOCUMENT"
,schema="Default"
)
public class Document implements java.io.Serializable {
#ManyToOne
#JoinColumn(name = "FormatID")
private Format format;
#Id
#Column(name = "DocumentID", unique = true, nullable = false)
private int documentId;
FORMAT :
#Entity
#Table(name="FORMAT"
,schema="Default"
)
public class Format implements java.io.Serializable {
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "FormatID")
private Set<Document> documents = new HashSet();
#Id
#Column(name = "FormatID", unique = true, nullable = false)
private int formatId;
format.hbm
<hibernate-mapping>
<class name="entity2.Format" table="FORMAT">
<id name="formatId" type="int">
<column name="FormatID" length="2000000000" />
<generator class="native" />
</id>
<set name="documents" table="DOCUMENT"
inverse="true" lazy="true" fetch="select">
<key>
<column name="FormatID" not-null="true" />
</key>
<one-to-many class="entity2.Document" />
</set>
document.hbm
<hibernate-mapping>
<class name="entity2.Document" table="DOCUMENT">
<id name="documentId" type="int">
<column name="DocumentID" length="2000000000" />
<generator class="native" />
</id>
<many-to-one name="format" class="entity2.Format" fetch="select">
<column name="FormatID" not-null="true" />
</many-to-one>
i want to retrieve all documents for format 1:
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Format f = (Format) session.get(Format.class, 1);
System.out.println(f.getName());
System.out.println(f.getDocuments());
documents is empty? where am i wrong?

If you define a relationship between classes, for example:
class Person {
#OneToMany(cascade=CascadeType.ALL,
fetch= FetchType.EAGER)
private Set<Email> emails = new HashSet();
// getters/setters and some other attributes are not shown
When you read an object from the database, you will get another object that has a relationship with it automatically.
Session s = HibernateUtil.getSessionFactory().openSession();
Person p = (Person) s.get(Person.class, 1);
s.close();
System.out.println(p.getName());
System.out.println(p.getEmails());
The following is an example of bidirectional one to one relationship.
class Person {
#OneToOne(cascade=CascadeType.ALL)
private Address address;
class Address {
#OneToOne(mappedBy=”address”)
private Person person

Hibernate is an ORM tool - the "O" stands for "object". Start with an Email object that maps to your table and columns. Then use HQL to query for Email instances that meet a particular restriction.
JTable or web page are display issues that are separate from the manner in which you query for objects.

You just write the query using a select statement for all of the values you wish to retrieve. Hibernate will return an array with those values in it with the indices in the same order as your select statement.
SELECT
FROM Person AS P, Address AS A, Order AS O, User AS U
WHERE P.id = 5
AND A.personId = P.id
AND O.personId = P.id
AND U.personId = P.id
This will return an array containing {person, address, List, User}

Related

How to map detached Collection(List, Set) or Map with Hibernate via annotations

I know, that there is a way to map Map via XML:
<set name="images"
table="ITEM_IMAGE"
order-by="IMAGENAME asc">
<key column="ITEM_ID"/>
<composite-element class="Image">
<property name="name" column="IMAGENAME" not-null="true"/>
<property name="filename" column="FILENAME" not-null="true"/>
<property name="sizeX" column="SIZEX" not-null="true"/>
<property name="sizeY" column="SIZEY" not-null="true"/>
</composite-element>
</set>
Is there way to do the same thing via annotations mapping, and how to persist it into separate table?
Thatks a lot!
For composite values or basic types it should be almost the same, first you need to tell hibernate that we are mapping to a collection
then specify the name of the table which should hold your map and the join column with your current entity , then you specify the key.
#Entity
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "Item_ID")
private Long itemId;
#ElementCollection
#CollectionTable(name="ITEM_IMAGE", joinColumns=#JoinColumn(name="ITEM_ID"))
#MapKeyColumn(name="ITEM_ID")
private Map<String, Image> contacts = new HashMap<String, Image>();
}
#Embeddable
public class Image {
//Specify your composite attributes with the column name for each
}
hope I did not miss anything

One object from two tables

I have two tables and want to map them to one object with Hibernate.
The reason for both tables is in the past and I wont change the frontend, which access data like this.
I have Table Event (Event_ID, Preview, img) and Event_Details (ID, Event_ID, content).
I prepare one class in Java:
public class Event {
private int event_ID;
private String preview;
private String img;
private String content;
//Getter and Setter
}
and following XML mapping file:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 16.03.2016 20:33:10 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="de.data.events.Event" table="ev1_event">
<id name="id" type="int">
<column name="Event_ID" />
<generator class="assigned" />
</id>
<property name="preview" type="java.lang.String">
<column name="ev1_preview" />
</property>
<property name="img" type="java.lang.String">
<column name="ev1_img" />
</property>
</class>
<class name="de.data.events.Event" table="pb1_event">
<id name="id" type="int">
<column name="id" />
<generator class="assigned" />
</id>
//some properties
</class>
The part, where I have to join table1 to table2 is missing. But I didn´t found a way to fix my problem.
First, you'd have your Hibernate entities. Yours are Event and EventDetail, but for fun, let's go with Person and Address in this example. The key here is that you need a one-to-one or many-to-one relationship between your tables. Otherwise, your resultset will come out weird (more on that later).
#Entity
#Table(name = "PERSON")
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "PERSON_ID")
public Integer id;
#Column(name = "NAME")
public String name;
#Column(name = "HOME_ADDRESS_ID")
public Integer homeAddressId;
#Column(name = "TEMP_ADDRESS_ID")
public Integer tempAddressId;
// . . . other fields,getters,setters
}
#Entity
#Table(name = "ADDRESS")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ADDRESS_ID")
public Integer id;
#Column(name = "STREET")
public String street;
#Column(name = "CITY")
public String city;
// . . . other fields,getters,setters
}
Then you'd have your target FlatObject POJO with the a constructor that will build it appropriately:
public class FlatObject {
public final String name;
public final String homeStreet;
public final String homeCity;
public final String tempStreet;
public final String tempCity;
public FlatEntity(String name, String homeStreet, String homeCity, String tempStreet, String tempCity) {
this.name = name;
this.homeStreet = homeStreet;
this.homeCity = homeCity;
this.tempStreet = tempStreet;
this.tempCity = tempCity;
}
// . . . other fields,getters
}
Finally, you'd leverage those objects with a Hibernate HQL SELECT where you join Person and Address and use their fields to construct a new FlatEntity:
SELECT new FlatEntity(p.name, ha.homeStreet, ha.homeCity, ta.tempStreet, ta.tempCity)
FROM
Person p, Address ha, Address ta
WHERE
p.homeAddressId = ha.id
and p.tempAddressId = ta.id
As you can see, the HQL statment will join Person to Address twice: once for the home address and once for the temp address.
The same will hold true in your case. So in your case, if you're joining Event e, EventDetail ed WHERE e.id = ed.eventId, just be sure there's only one detail row per Event. Otherwise you'll get multiple rows when you have more than one details or you'll drop rows (because of the inner join) when an event has no details.

Hibernate query/criteria returning duplicate data

criteria = createCriteria("employee");
criteria.add(Restrictions.eq("name", "Jack"));
criteria.createAlias("certificate", "cert");
criteria.add(Restrictions.eq("cert.certType", "MSFT"));
criteriaList = criteria.list();
Given the data below, I think the query above should have returned one record that contains a set(set size=2) of certificates but I get the same record duplicated twice(once for each record in Certificate table). Why is this happening?
Employee Table:
EMP_ID NAME
123 Jack
111 Mary
000 Larry
Certificate table data
emp_id certificate_type seq_no
123 MSFT 1
123 MSFT 2
111 English 1
employee.hbm.xml
<class name="com.Employee" table="Employee" entity-name="employee" mutable="false">
<cache usage="read-only"/>
<id name="id" column="employee_id"/>
<set name="certificate" fetch="select" inverse="true" lazy="false" >
<key column="employee_id" />
<one-to-many class="com.Certificate" entity-name="CertificateType"/>
</set>
</class>
certificate.hbm.xml
<class name="com.Certificate" table="Certificate" entity-name="CertificateType" mutable="false">
<cache usage="read-only"/>
<composite-id class="com.usps.nom.tops.model.impl.DispatchLegPKImpl" mapped="true">
<key-property name="empId" column="emp_id" />
<key-property name="seqNo" column="SEQ_NO" />
</composite-id>
<property name="certType" column="certificate_type"/>
</class>
POJOs
public class Employee {
private int id;
private String ame;
//getters and setters
public boolean equals(Object obj){}
}
public class Certificate {
private int emp_id;
private String certType;
private String seqNo;
//getters and setters
public boolean equals(Object obj){}
}
EDIT:
If I put the result (ie criteriaList in my example) in a set, then it gets rid of the duplicate record.
Set<Employee> empSet = new HashSet<Employee>(criteriaList);
I'm newbie in Hibernate, but faced with similar problem (parent records are duplicated by join)
I have added FetchMode.SUBSELECT annotation (I prefer annotations)
#OneToMany
#Fetch(FetchMode.SUBSELECT)
It looks like working perfectly for me without duplicating data.

Hibernate parent-child mapping

I'm trying to map an order and its order items in Hibernate. An order item should not be able to reference its parent order:
public class Order {
private long id;
private Set<OrderIter> orderItems = new HashSet<OrderItem>();
public long id() {
return id;
}
public void add(OrderItem item) {
item.setItemNumber(orderItems.size() + 1);
orderItems.add(item);
}
public Set<OrderItem> orderItems() {
return Sets.newHashSet(orderItems);
}
}
public class OrderItem {
private int itemNumber;
public int itemNumber() {
return itemNumber;
}
public void setItemNumber(int itemNumber) {
this.itemNumber = itemNumber;
}
}
The objective is to have Hibernate automatically persist an order item when it's added to an order, like this:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Order order = (Order) session.load(Order.class, orderId);
OrderItem item = new OrderItem();
order.add(item);
// Done
session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
I looked at Chapter 24. Example: Parent/Child, but in this example the child has a reference to the parent. I'm now trying to map it using Collections of dependent objects:
<class name="Order" table="ORDERS">
<id name="id" column="ORDER_ID" access="field">
<generator class="native" />
</id>
<set name="orders" table="ORDER_ITEMS" access="field">
<key column="id" />
<composite-element class="OrderItem">
<property name="ItemNumber" access="field" />
</composite-element>
</set>
</class>
This is almost working, but the combination of order id and item number should be unique. How can I meet all these criteria with a Hibernate mapping?
Here the one-to-many association between Order->OrderItem is mapped using a JOIN TABLE.
The one-to-many association is mapped with a many-to-many with unique set to true.
(since one-to-many is not aware of a join table on the set)
<class name="Order" table="ORDERS">
<set name="orders" table="ORDER_ORDERITEMS_RT">
<key column="ORDER_ID" />
<many-to-many name="OrderItem" unique="true" column="ORDERITEM_ID"/>
</set>
</class>
<class name="OrderItem table="ORDERITEMS">
</class>
The above mapping satisfies
OrderItem not having a reference to Order. As the mapping are in a separate table
One-to-many association makes the orderid-orderitemid pair unique.
You can put appropriate cascading on the set to allow saving the orderItem when added to the list on the Order. (Not shown in the mapping)
Hope this helps.

Hibernate: How to select a single item based on a foreign key column that is part of an association mapping?

Hullo,
So... I have the following objects:
public class Person {
// some other getters/setters omitted.
void setAddress(Address addy) {
// omitted
}
Address getAddress() {
// omitted
}
}
public class Address {
Integer getId() {
// omitted
}
}
And, I have the following hibernate mappings:
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
unique="true"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
So, there is a one to one mapping from Person to Address, Person has the foreign key to Address.
What I'm trying to do is fetch a Person object from a given Address ID... but I can't seem to figure out the correct HQL syntax:
public Person getPersonFromAddress(Address address) {
Query query = this.session.createQuery("select p from Person as p where p.address_id = " + address.getId());
#SuppressWarnings("unchecked")
Person p = (Person)query.uniqueResult();
return p;
}
I know I don't have a mapping from the foreign key column to a property on Person. Everytime I try to add one I get an exception saying I'm using the same column twice? I don't see what would be wrong with that :).
Anyways, what would be the best way to fetch the Person given an Address? Any help would be appreciated.
You should be able to do this
Query query = this.session.createQuery("select p from Person as p where p.address=:address")
.setParameter("address",address);

Categories

Resources