I have the following classes:
Guide class:
public abstract class Guide
{
private Long idGuide;
private String name;
private GuideContainer parent;
/** GETTERS & SETTERS*/
}
GuideContainer:
public class GuideContainer extends Guide
{
private Guide children;
/** GETTER & SETTERS */
}
GuideFile:
public class GuideFile extends Guide
{
private String uri;
/**GETTERS & SETTERS */
}
with the following mappings:
For Guide:
<hibernate-mapping>
<class name="Guide" table="guides" abstract="true">
<id name="idGuide" type="integer" column="idGuide">
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String" column="name" />
<discriminator column="type" type="java.lang.String" />
<many-to-one class="GuideContainer" fetch="join" name="parent">
<column name="parent" />
</many-to-one>
</class>
</hibernate-mapping>
GuideFile:
<hibernate-mapping>
<subclass extends="Guide" name="GuideFile" discriminator-value="file">
<property name="uri" type="java.lang.String" column="uri" />
</subclass>
</hibernate-mapping>
GuideContainer:
<hibernate-mapping>
<subclass extends="Guide" name="GuideContainer" discriminator-value="container">
<set fetch="select" inverse="true" lazy="true" name="children" sort="unsorted" table="children">
<key>
<column name="parent" not-null="false" />
</key>
<one-to-many class="Guide" />
</set>
</subclass>
</hibernate-mapping>
When I try to get all the guides with a given parent
Query query = getSession().createQuery("from Guide g where parent = :parent order by type").setParameter("parent", parent);
List<Guide> guides= query.list();
return guides;
I am getting the following exception:
IllegalArgumentException occurred calling getter of Guide.idGuide
And after that:
java.lang.IllegalArgumentException: object is not an instance of declaring class
What am I doing wrong?
Solved. Query should have been:
from Guide g where parent.idGuide = :parent order by type
Related
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" />
I'm having a hard time to figure this thing out. I have managed to create this type of mapping using annotations, but XML configuration is giving me headache for hours. These are my POJOs (getters ans setters are omitted):
public class Stock implements Serializable {
private static final long serialVersionUID = 8724254922362918916L;
private int stockId;
private String stockCode;
private String stockName;
private Set<StockCategory> stockCategories;
}
public class Category implements Serializable {
private static final long serialVersionUID = -3719693878172387644L;
private int categoryId;
private String name;
private String desc;
private Set<StockCategory> stockCategories;
}
public final class StockCategoryId implements Serializable {
private static final long serialVersionUID = -6894097209574496516L;
private int stockId;
private int categoryId;
}
public class StockCategory implements Serializable {
private static final long serialVersionUID = 691323506089277225L;
private StockCategoryId stockCategoryId;
private Stock stock;
private Category category;
private Date createdDate;
private String createdBy;
}
And those are hibernate mapping files:
<class name="com.rmilovic.hibernate.examples.models.Stock" table="STOCK">
<id name="stockId" column="STOCK_ID" type="int">
<generator class="identity" />
</id>
<property name="stockCode" type="string">
<column name="STOCK_CODE" length="10" not-null="true" unique="true" />
</property>
<property name="stockName" type="string">
<column name="STOCK_NAME" length="10" not-null="true" unique="true" />
</property>
<set name="stockCategories" table="STOCK_CATEGORY" inverse="true"
lazy="true" fetch="select" cascade="all">
<key column="STOCK_ID" not-null="true" />
<one-to-many class="com.rmilovic.hibernate.examples.models.StockCategory" />
</set>
</class>
<class name="com.rmilovic.hibernate.examples.models.Category" table="CATEGORY">
<id name="categoryId" column="CATEGORY_ID" type="int">
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="NAME" not-null="true" length="10" unique="true" />
</property>
<property name="desc" type="string">
<column name="DESC" not-null="true" />
</property>
<set name="stockCategories" table="STOCK_CATEGORY" lazy="true" inverse="true"
fetch="select" cascade="all">
<key column="CATEGORY_ID" not-null="true" />
<one-to-many class="com.rmilovic.hibernate.examples.models.StockCategory" />
</set>
</class>
<class name="com.rmilovic.hibernate.examples.models.StockCategory" table="STOCK_CATEGORY">
<composite-id name="stockCategoryId"
class="com.rmilovic.hibernate.examples.models.StockCategoryId">
<key-property name="stockId" type="int" column="STOCK_ID" />
<key-property name="categoryId" type="int" column="CATEGORY_ID" />
</composite-id>
<property name="createdDate" type="date">
<column name="CREATED_DATE" not-null="true" length="10" unique="true" />
</property>
<property name="createdBy" type="string">
<column name="CREATED_BY" not-null="true" length="10" unique="true" />
</property>
<many-to-one name="stock" column="STOCK_ID"
class="com.rmilovic.hibernate.examples.models.Stock"
insert="false" update="false" />
<many-to-one name="category" column="CATEGORY_ID"
class="com.rmilovic.hibernate.examples.models.Category"
insert="false" update="false" />
</class>
Schema seems to be good but I'm getting:
Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.rmilovic.hibernate.examples.models.Category
when I'm trying to save data.
This is the code which saves data:
final Session session = HibernateUtilities.openSession();
session.beginTransaction();
final Stock stock = new Stock("BLA", "Test");
final Category category = new Category("consumer", "consumer company");
final StockCategory stockCategory = new StockCategory(new Date(), "me");
stockCategory.setCategory(category);
stockCategory.setStock(stock);
stock.getStockCategories().add(stockCategory);
category.getStockCategories().add(stockCategory);
session.save(stock);
session.getTransaction().commit();
HibernateUtilities.closeSession();
I want to save an object to my sub-class ArticleZoning whose super class Zoning contain a List of Class zoneData which also contain a class ZoneCoordinate. When I save the object of my sub-class ArticleZoning it gives an exception.
org.hibernate.PropertyValueException: not-null property references a null or transient value: com.qait.cdl.eon.commons.domain.ZoneData._com.qait.cdl.eon.commons.domain.Zonning.zoneDatasBackref
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:101)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210).....
Here is *Zonning hbm*Mapping file:-
<class name="Zonning" table="zoning">
<id name="id" column="id" type="long">
<generator class="native" />
</id>
<list name="zoneDatas" lazy="false" cascade="all-delete-orphan" >
<key column="zoning_id" not-null="true"/>
<list-index column="idx" base="1" />
<one-to-many class="com.qait.cdl.eon.commons.domain.ZoneData" />
</list>
<many-to-one class="com.qait.cdl.eon.commons.domain.MagazineIssue" unique="true" column="issue_id" name="issue"/>
<property name="pageNumber" column="article_on_pageNumber" type="string" not-null="true" />
<joined-subclass name="ArticleZoning" extends="Zonning" table="article_zoning">
<key column="article_id"/>
<property name="articleTitle" column="article_title" type="string" not-null="true" />
<property name="articleOrder" column="article_order" type="int" not-null="true" />
<property name="articleFileId" column="article_file_id" type="string" not-null="true" />
<property name="articleType" column="article_type">
<type name="org.hibernate.type.EnumType">
<param name="type">12</param>
<param name="enumClass">com.qait.cdl.eon.common.constants.ArticleType</param>
</type>
</property>
<property name="articleSubTitle" column="article_sub_title" type="string" not-null="true" />
<property name="articleGenre" column="article_genre">
<type name="org.hibernate.type.EnumType">
<param name="type">12</param>
<param name="enumClass">com.qait.cdl.eon.common.constants.Genre</param>
</type>
</property>
</joined-subclass>
<joined-subclass name="AdvertisementZoning" extends="Zonning" table="advertisement_zoning">
<key column="advertisement_id" />
<property name="adVendor" column="ad_vendor" type="string" not-null="true" />
<property name="vendorUrl" column="vendor_url" type="string" not-null="true" />
<property name="adProduct" column="ad_product" type="string" not-null="true" />
<list name="adKeywords" table="ad_keywords" lazy="false" cascade="all">
<key column="ad_keywords_id" />
<list-index base="0" column="idx"/>
<element column="keywords" type="string" />
</list>
</joined-subclass>
</class>
Here is ZoneData Hbm
<id name="id" column="id" type="long">
<generator class="native" />
</id>
<property name = "zoneOrder" column = "zone_order" type = "int" not-null="true"/>
<property name = "zoneFileId" column = "zone_file_id" type = "string" not-null="true"/>
<property name = "zoneShape" column = "zone_shape" type = "string" not-null="true" access="field"></property>
<many-to-one name="coordinates" column="coordinates_id" lazy="false" class="com.qait.cdl.eon.commons.domain.ZoneCoordinates"
unique="true" not-null="true" cascade="all-delete-orphan"/>
</class>
Here is ZoneCoordinate hbm
<class name="ZoneCoordinates" table="zone_coordinates">
<id name="id" column="id" type="long">
<generator class="native" />
</id>
<property name = "leftTopX" column = "left_top_x" type = "float" not-null="true" />
<property name = "leftTopY" column = "left_top_y" type = "float" not-null="true" />
<property name = "rightBottomX" column = "right_bottom_x" type = "float" not-null="true" />
<property name = "rightBottomY" column = "right_bottom_y" type = "float" not-null="true" />
</class>
Here is Zoning pojo
class Zoning{
private List<ZoneData> zoneDatas =new ArrayList<>();
private MagazineIssue issue;
private String pageNumber;
//getter and setter
}
Here is ZoneData POJO
class ZoneData{
private int zoneOrder;
private String zoneFileId ;
private ZoneCoordinates coordinates;
private final String zoneShape = "RECT";
//getter and setter
}
Here is ArticleZoning POJO
class ArticleZoning extends Zoning{
private String articleTitle;
private String articleOrder;
private ArticleType articleType;
private String articleFileId;
private String articleSubTitle;
private Genre articleGenre;
//getter and setter
}
Here is ZoneCoordinate POJO
class ZoneCoordinate{
private float leftTopX;
private float leftTopY;
private float rightBottomX;
private float rightBottomY;
//getter and setter
}
First, ArticleZoning POJO has articleOrder as String type. Your Zonning.hbm says articleOrder is of int type.
Secondly, as zoning table is unable to save, hence its foreign key is null.
I've got table in MySQL database with this structure:
And hibernate mapping for object PatientDAO here:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cz.cvut.fit.genepi.models.PatientDAO" table="patient">
<id name="_id" type="int">
<column name="id" precision="6" scale="0" not-null="true" />
<generator class="assigned" />
</id>
<property name="_nin" type="long">
<column name="nin" length="20" not-null="false" />
</property>
<property name="_birthday" type="date">
<column name="birthday" length="7" not-null="true" />
</property>
<property name="_gender" type="string">
<column name="gender" length="10" not-null="true" />
</property>
<property name="_doctor_id" type="int">
<column name="doctor_id" precision="6" scale="0" not-null="false" />
</property>
<property name="_deleted" type="int">
<column name="deleted" precision="1" scale="0" not-null="false" />
</property>
<property name="_checked" type="int">
<column name="checked" precision="1" scale="0" not-null="false" />
</property>
<property name="_contact_id" type="int">
<column name="contact_id" precision="6" scale="0" not-null="false" />
</property>
<property name="_comment_id" type="int">
<column name="comment_id" precision="6" scale="0" not-null="false" />
</property>
</class>
</hibernate-mapping>
But when I'm trying to get some sample data from dtb and print them out, I get only 0. This happens for any possible property of Patient DAO. And for any id of searched patient.
I'm sure, that patient with id==0 is contained in that table.
findByID function:
public T findByID(Class<T> myClass, int id) {
Session hibernateSession = this.getSession();
T t = null;
t = (T) hibernateSession.get(myClass, id);
return t;
}
part of PatientDAO (without setters and getters):
public class PatientDAO implements java.io.Serializable {
/**
* generated serialVersionUID
*/
private static final long serialVersionUID = -8172690860460945951L;
private int _id;
private long _nin;
private Date _birthday;
private String _gender;
private int _doctor_id;
private int _deleted;
private int _checked;
public int get_checked() {
return _checked;
}
}
My personal tip is that I got there something wrong in my mapping, because for simplier objects it worked well. But I'm quite new to hibernate, so I can't figure out, what can be there wrong.. I'd be really glad if someone could help.
problem was in bad mapping... I actually dind't see, that nin should be varchar and I declared it as long