I have to perform hibernate mapping only by using annotation method in subclass according to following scenario in Spring MVC3 enviroment:
1) I have class called Event.java from xxxx.jar library with following properties
public Class Event{
public integer id;
public String start_date;
public String start_date;
public String text;
}
2) POJO class CustomEvent.java extending Event.java class using inheritance with following structure.
public class CustomEvent extends Event implements Serializable {
private static final long serialVersionUID = 1L;
public String user;
public String type;
public String contact;
public String status;
}
3) Im able to perform hibernate mapping using XML in following way
<hibernate-mapping>
<class name="<package>.model.CustomEvent" table="events">
<id column="event_id" name="id" type="java.lang.Integer">
<generator class="increment"/>
</id>
<property column="start_date" name="start_date" type="timestamp"/>
<property column="end_date" name="end_date" type="timestamp"/>
<property column="text" name="text" type="java.lang.String"/>
<property column="user" name="user" type="java.lang.String"/>
<property column="type" name="type" type="java.lang.String"/>
<property column="contact" name="contact" type="java.lang.String"/>
<property column="status" name="status" type="java.lang.String"/>
</class>
</hibernate-mapping>
and its working fine.
Q) How I can achieve the same thing with JPA/Hibernate annotations?
I am new bay for Hibernate / Spring framework.
Note: Event class is present in .jar library, not able to see the code exactly
Related
I am trying to retrieve a list of products with they're associated offers. After iterating through the result of the query I want to be able to use the getters/setters from the products class but I know it's not working because the query is not returning an instance of Product.
function to grab the products:
public List<Product> getProducts() {
factory = (new Configuration()).configure().buildSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();
List<Product> products = new ArrayList<Product>();
Query query = session.createQuery("from Product p INNER JOIN p.offers");
//The castList is declared and explained at the bottom of listing
List<Product> list = query.list();
Iterator<Product> iter = list.iterator();
while (iter.hasNext()) {
Product product = iter.next();
System.out.println(product);
}
}
Hibernate mapping for Offer:
<hibernate-mapping>
<class name="shoppingbasket.Offer" table="offers">
<id name="offerID" type="integer" access="field">
<column name="OfferID" />
<generator class="assigned" />
</id>
<property name="offerDescription" type="java.lang.String" access="field">
<column name="OfferDescription" length="60" not-null="true"/>
</property>
<property name="shortDescription" type="java.lang.String" access="field">
<column name="ShortDescription" length="10" not-null="false"/>
</property>
<property name="TFTPOTGroup" type="java.lang.Integer" access="field">
<column name="TFTPOTGroup" length="4" not-null="false" default="null"/>
</property>
<property name="discountPercentage" type="java.lang.Double" access="field">
<column name="DiscountPercentage" not-null="false" default="null"/>
</property>
</class>
Hibernate mapping for Product:
<hibernate-mapping>
<class name="shoppingbasket.Product" table="products">
<id name="productID" type="integer" access="field">
<column name="ProductID" />
<generator class="assigned" />
</id>
<property name="offerID" type="java.lang.Integer" access="field">
<column name="OfferID" />
</property>
<property name="productName" type="java.lang.String" access="field">
<column name="ProductName" length="40" not-null="true"/>
</property>
<property name="unitPrice" type="java.math.BigDecimal" access="field">
<column name="UnitPrice"/>
</property>
<one-to-one name="offers" class="shoppingbasket.Offer" />
</class>
Product class:
public class Product implements java.io.Serializable {
private Integer productID;
private Integer offerID;
private String productName;
private BigDecimal unitPrice;
private Offer offer;
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getOfferID() {
return this.offerID;
}
public void setOfferID(Integer offerID) {
this.offerID = offerID;
}
public Offer getOffers() {
return offer;
}
public void setOffers(Offer offer) {
this.offer = offer;
}
//more getters/setters
}
Offer class:
public class Offer
{
private Integer offerID;
private String offerDescription;
private String shortDescription;
private Integer TFTPOTGroup;
private Double discountPercentage;
public Integer getOfferID() {
return offerID;
}
public void setOfferID(Integer offerID) {
this.offerID = offerID;
}
//more getters/setters
}
Any help would be hugely appreciated
#Potential Unnecessary Projections Data:
Since you're not specifying SELECT clause in the query and putting explicit joins, hibernate will return 2 objects per row (Product, Offers), wherein Product object might already be populated with the Offer data due to underlying mapping associations.
Try adding select clause to the query and see if it casts correctly
Add SELECT p FROM ... to the query
I have 2 classes:
User
RentedCar
public class User implements Serializable{
private String userName;
private Integer userId;
private String userParent;
}
public class RentedCar implements Serializable{
private Date stopDate;
private Date startDate;
private String carName;
private Integer carId;
private Integer userId; // Some userId from User.
}
These classes have their respective hbm.xml files. The underlying tables are un-related. Which means that I know that the userId in RentedCar is associated with the userId in User but there is no PK/FK relationship between them. I need to add a many-to-one association between RentedCar and User and one-to-many association between User and RentedCar. How should I do this in the hbm.xml files ?
These are the xml mappings:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="User" table="user">
<composite-id>
<key-property name="userName" column="user_name" type="string"/>
<key-property name="userParent" column="user_parent" type="string"/>
</composite-id>
<property name="userId" column="user_id" type="int"></property>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="RentedCar" table="rented_car">
<composite-id>
<key-property name="stopDate" column="stop_date" type="date" />
<key-property name="carId" column="car_id" type="int" />
<key-property name="userId" column="user_id" type="int" />
</composite-id>
<property name="startDate" column="start_date" type="date"></property>
<property name="carName" column="car_name" type="float"></property>
</class>
</hibernate-mapping>
I think you should have something in your classes show that there is one-to-many relationship in order to do this in hbm.xml files :
public class User implements Serializable{
private String userName;
private Integer userId;
private String userParent;
private Set<RentedCar> rentedCars;
}
public class RentedCar implements Serializable{
private Date stopDate;
private Date startDate;
private String carName;
private Integer carId;
private User user;
}
Then in RentedCar.hbm.xml you can inside use :
<many-to-one name="user" class="User">
<column name="userId" not-null="true"></column>
</many-to-one>
And in User.hbm.xml :
<set name="rentedCars" table="rented_car" fetch="select">
<key>
<column name="userId" not-null="true"></column>
</key>
<one-to-many class=" RentedCar "/>
</set>
This tutorial may help you http://www.tutorialspoint.com/hibernate/hibernate_one_to_many_mapping.htm
I am trying to save to two tables in SQL server using Hibernate:
ORDER and ORDER_ITEM
I get an error:
Attribute "type" must be declared for element type "column".
Initial SessionFactory creation failed.org.hibernate.InvalidMappingException: Unable to read XML.
This produces a NullPointerException
If I understand correctly, this means that when I try to save to the order_item table, the getter for the foreign key is empty, but how would I set it if is designed to 'Autoincrement', I thought that hibernate would handle this in it's transaction.
Below are my POJO's and Hibernate mappings. I have omitted the getters and setters from this copy/paste, but they are present in my actual code
I am also successful in saving just to the ORDER table if I remove the set
Order.java:
public class Order {
public Order(){
super();
}
private int orderId;
private Set<LineItem> items;
private String strPhone;
private String strEmail;
private String strFirstName;
private String strLastName;
private String strParentFirstName;
private String strParentLastName;
private String strOrganizationName;
private String strOrganizationType;
private String strComment;
}
order.hbm.xml:
<hibernate-mapping>
<class name="dbobjects.Order" table="orders">
<id name="orderId" type="integer" column="order_id">
<generator class="increment"/>
</id>
<property name="strPhone" type="string" column="phone_number"/>
<property name="strFirstName" type="string" column="first_name"/>
<property name="strLastName" type="string" column="last_name"/>
<property name="strParentFirstName" type="string" column="parent_first_name"/>
<property name="strParentLastName" type="string" column="parent_last_name"/>
<property name="strOrganizationName" type="string" column="organization_name"/>
<property name="strOrganizationType" type="string" column="organization_type"/>
<property name="strComment" type="string" column="comments"/>
<set name="items" table="order_item" fetch="select" cascade="all">
<key>
<column name="orderId" type="java.lang.Integer"/>
</key>
<one-to-many class="dbobjects.LineItem"/>
</set>
</class>
LineItem.java:
public class LineItem {
public LineItem(){
super();
}
private int orderItemId;//this will be the primary key
private int orderId;//this is the foreign key to the order
private String age;
private String gender;
private String type;
private String itemSize;
private int itemQuantity;
}
lineItem.hbm.xml:
<id column="order_item_id" name="orderItemId" type="integer">
<generator class="increment"/>
</id>
<property column="age" name="age" type="string"/>
<property column="gender" name="gender" type="string"/>
<property column="quantity" name="itemQuantity" type="integer"/>
<property column="size" name="itemSize" type="string"/>
<property column="clothing_type" name="clothingType" type="string"/>
<many-to-one name="orderId" class="dbobjects.Order" fetch="select" column="order_id" type="java.lang.Integer"/>
This is where the error is thrown when I Instanciate the session:
**session = HibernateUtil.getSessionFactory().openSession();**←
try{
session.beginTransaction();
session.save(order);
session.getTransaction().commit();
So the question is: How do I handle this situation with 'autoincrement' primary key that is not accessible to another table as a foreign key
So, There were a few problems:
In order to submit a 'child' to the database, I needed to show who is the parent.
This means that my LineItem Class needed a
Order order;
property instead of a simple
private String orderID;
this was accomplished after the Order object was ready to be submitted to the DB but before the actual call:
for (LineItem item : order.getItems()) {
item.setOrder(order);
}
I also changed my DTD's from !DOCTYPE hibernate-configuration SYSTEM classpath://org/hibernate/hibernate-mapping-3.0.dtd"
to
!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"
Just add "type" attribute like this :
<column name="orderId" type="java.lang.Integer"/>
Try to replace :
<many-to-one name="orderId" column="order_id" class="dbobjects.Order" cascade="all">
<column name="orderId" type="java.lang.Integer"/>
</many-to-one>
by
<many-to-one name="orderId" column="order_id" class="dbobjects.Order" cascade="all"/>
I have the following classes
class Condition{
public Long id;
public Long ParentConditionId;
public Int order;
}
class NotCondition extends Condition {
public Condition childCondition;
}
class BooleanCondition extends Condition {
public Collection<Condition> children;
}
class StringCondition extends Condition {
public String value;
}
These classes are represented by a condition table with the following columns
Id bigint
Type varchar
ConditionOrder int
StringValue varchar
ParentConditionId bigint
How do I map the NotCondition to its child using hibernate mapping so that the childs ParentConditionId column contains the id of the NotCondition?
My mapping file is
<hibernate-mapping>
<class name="conditions.Condition" table="Condition">
<id column="Id" name="id" access="field">
<generator class="increment"/>
</id>
<discriminator type="string" column="Type"/>
<property name="order" column="ConditionOrder" access="field"/>
<property name="parentConditionId" column="ParentConditionId" access="field"/>
<subclass name="conditions.NotCondition" discriminator-value="NOT">
<!-- What to put here? -->
</subclass>
<subclass name="conditions.BooleanCondition" discriminator-value="BOOLEAN">
<list name="children" access="field" cascade="all" lazy="false">
<key><column name="ParentConditionId"></column></key>
<list-index column="ConditionOrder"/>
<one-to-many class="conditions.Condition"/>
</list>
</subclass>
<subclass name="conditions.StringCondition" discriminator-value="STRING" >
<property name="value" column="StringValue" access="field"/>
</subclass>
</class>
</hibernate-mapping>
explore these :
#Inheritance(strategy=InheritanceType.JOINED)
I suggest you to use annotations..
Below link contains both Annatation and xml configurations..
link here
First, in class Condition, I would replace:
public Long ParentConditionId;
with:
public Condition parentCondition;
I would map is like so:
<many-to-one name="parentCondition" class="conditions.Condition" column="ParentConditionId" />
then, I would map childCondition (in subclass NotCondition) as:
<one-to-one name="childCondition" class="conditions.Condition" property-ref="parentCondition" />
Am using Hibernate 3.6
Below is Employee class code.
public class Employee {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
Below is Employee.hbm.xml file,
<class name="com.testing.hibernate.Employee" table="HIB_EMPLOYEE">
<meta attribute="class-description">
This class contains the Employee details.
</meta>
<id name="id" type="int" column="id">
<generator class="sequence"></generator>
</id>
<property name="firstName" column="first_name" type="string"></property>
<property name="lastName" column="last_name" type="string"></property>
<property name="salary" column="salary" type="int"></property>
</class>
I have created sequence in Database. Below SS for reference. How can I overcome the exception that am getting?
You have to give the reference of the sequence to hibernate.
<generator class="sequence">
<param name="sequence">SEQUENCE_NAME</param>
</generator>
What annotation can i use to do this?
i've tried
#GeneratedValue(strategy=GenerationType.SEQUENCE , generator = <SEQUENCE_NAME>")
without any success
edit:
it seams that the generator have to also be created
#SequenceGenerator(name="<GEN_NAME>", sequenceName="<SEQUENCE_NAME>")