i have three entity and Main(User) enitiy is in relation with other two entity,how can i retrive list of three entities from database in one query using hibernate
package hib.test;
import java.util.HashSet;
import java.util.Set;
public class Country {
private Integer id;
private String country;
private Set<User> userList = new HashSet<User>();
public Country() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Set<User> getUserList() {
return userList;
}
public void setUserList(Set<User> userList) {
this.userList = userList;
}
}
User.java
package hib.test;
public class User {
private Integer id;
private UserType userType;
private Country country;
public User() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public UserType getUserType() {
return userType;
}
public void setUserType(UserType userType) {
this.userType = userType;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
}
UserType.java
package hib.test;
import java.util.HashSet;
import java.util.Set;
public class UserType {
private Integer id;
private String userType;
private Set<User> userList = new HashSet<User>();
public UserType() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public Set<User> getUserList() {
return userList;
}
public void setUserList(Set<User> userList) {
this.userList = userList;
}
}
country.hbm.xml
<?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 Jun 6, 2012 1:12:01 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="hib.test.Country" table="COUNTRY">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="country" type="java.lang.String">
<column name="COUNTRY" />
</property>
<set name="userList" table="USER" inverse="false" lazy="true">
<key>
<column name="ID" />
</key>
<one-to-many class="hib.test.User" />
</set>
</class>
</hibernate-mapping>
user.hbm.xml
<?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 Jun 6, 2012 1:12:01 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="hib.test.User" table="USER">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="assigned" />
</id>
<many-to-one name="userType" class="hib.test.UserType" fetch="join">
<column name="USERTYPE" />
</many-to-one>
<many-to-one name="country" class="hib.test.Country" fetch="join">
<column name="COUNTRY" />
</many-to-one>
</class>
</hibernate-mapping>
usertype.hbm.xml
<?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 Jun 6, 2012 1:12:01 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="hib.test.UserType" table="USERTYPE">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="userType" type="java.lang.String">
<column name="USERTYPE" />
</property>
<set name="userList" table="USER" inverse="false" lazy="true">
<key>
<column name="ID" />
</key>
<one-to-many class="hib.test.User" />
</set>
</class>
</hibernate-mapping>
How can i retrive List<User>, List<Country> and List<UserType> with one query
EDIT
public static List<UserType> getUserTypeList() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
List<UserType> list = null;
try {
transaction = session.beginTransaction();
list = session.createQuery("from UserType as u").list();
if (list != null) {
for (UserType uType : list)
Hibernate.initialize(uType.getUserList());
}
transaction.commit();
} catch (Exception e) {
if (transaction != null)
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
return list;
}
Actually I have 1 JTable and Two combo box each for UserType and Country
So when i select any data in combo box JTable data should be filter according to selected value and in memory it shoud be save selected UserType and Country object.
if you want relational data at once and memory is not an issue, do lazy="false"
try defining fetch type to EAGER on you user mapping, that way when you load your user it will load the country and userType.
You need three queries to do that:
select u from User u;
select ut from UserType ut;
select c from Country c;
EDIT:
If what you actually want is a list of all the user types, with the users of each user type, and the country of each user of each user type, all this loaded in a single query, then you need fetch joins, as explained in the Hibernate documentation:
select userType from UserType userType
left join fetch userType.users user
left join fetch user.country
Related
I am encountering an error when I implement Hibernate JPA mapping when I built it in Apache Maven.
Description Resource Path Location Type
The persistence.xml file does not have supported content for this JPA
platform. persistence.xml /LearningManagementService/src/main/resources/META-INF JPA Problem
My src/main/java has a package of com.ph.deped.model
User.java
package com.ph.deped.model;
/**
* User generated by hbm2java
*/
public class User implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -2357935130826100477L;
private long id;
private Privilege privilege;
private String username;
private String password;
public User() {
}
public User(Privilege privilege, String username, String password) {
this.privilege = privilege;
this.username = username;
this.password = password;
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public Privilege getPrivilege() {
return this.privilege;
}
public void setPrivilege(Privilege privilege) {
this.privilege = privilege;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
Privilege.java
package com.ph.deped.model;
// Generated May 7, 2018 9:04:03 PM by Hibernate Tools 5.2.3.Final
import java.util.HashSet;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* Privilege generated by hbm2java
*/
public class Privilege implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 910980850904284147L;
private long id;
private String description;
#JsonIgnore
private Set<User> users = new HashSet<User>(0);
public Privilege() {
}
public Privilege(String description, Set<User> users) {
this.description = description;
this.users = users;
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<User> getUsers() {
return this.users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
then my hbm.xml mapping is located in src/main/resources with a package of com.ph.deped.model same with the entity objects
User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="true" default-access="property" default-
cascade="none" default-lazy="true">
<class catalog="elearning" dynamic-insert="false" dynamic-update="false" mutable="true" name="com.ph.deped.model.User" optimistic-lock="version" polymorphism="implicit" select-before-update="false" table="user">
<id name="id" type="long">
<column name="id"/>
<generator class="identity"/>
</id>
<many-to-one class="Privilege" embed-xml="true" fetch="select" insert="true" name="privilege" not-found="exception" optimistic-lock="true" unique="false" update="true">
<column name="privilege_id"/>
</many-to-one>
<property generated="never" lazy="false" name="username" optimistic-lock="true" type="string" unique="false">
<column name="username"/>
</property>
<property generated="never" lazy="false" name="password" optimistic-lock="true" type="string" unique="false">
<column name="password"/>
</property>
</class>
</hibernate-mapping>
Privilege.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="true" default-access="property" default-
cascade="none" default-lazy="true">
<class catalog="elearning" dynamic-insert="false" dynamic-update="false" mutable="true" name="com.ph.deped.model.Privilege" optimistic-lock="version" polymorphism="implicit" select-before-update="false" table="privilege">
<id name="id" type="long">
<column name="id"/>
<generator class="identity"/>
</id>
<property generated="never" lazy="false" name="description" optimistic-lock="true" type="string" unique="false">
<column name="description"/>
</property>
<set embed-xml="true" fetch="select" inverse="true" lazy="true" mutable="true" name="users" optimistic-lock="true" sort="unsorted" table="user">
<key on-delete="noaction">
<column name="privilege_id"/>
</key>
<one-to-many class="User" embed-xml="true" not-found="exception"/>
</set>
</class>
</hibernate-mapping>
and lastly my persistence.xml is located at META-INF/persistence.xml under src/main/resources
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_1_1.xsd"
version="1.1">
<persistence-unit name="Elearning" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>/com/ph/deped/model/UserLogin.hbm.xml</mapping-file>
<mapping-file>/com/ph/deped/model/Privilege.hbm.xml</mapping-file>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="1a0b1c6d0d6c1b3aA#"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
<property name="hibernate.show_sql" value="false"/>
</properties>
</persistence-unit>
</persistence>
I'm trying to create a one to many relation between two tables. TestCase has a FK called Type
Basically many testCases can have one type but a testCase can only have one type.
What am I missing here?
TestCase table
TestType table
But I'm getting
Unkown column idtestType in field list
Model
public class TestCase {
private int id;
private String name;
private TestType type;
private byte[] data;
private String creationDate;
private String createdBy;
public TestCase() {
}
public TestCase(String name, TestType type, byte[] data, String creationDate, String createdBy) {
this.name = name;
this.type = type;
this.data = data;
this.creationDate = creationDate;
this.createdBy = createdBy;
}
TestCase.xml
<hibernate-mapping>
<class name="com.atp.Model.TestCases.TestCase" table="testCases">
<meta attribute="class-description">
This class contains the testCases details.
</meta>
<id name="id" type="int" column="idtestCase">
<generator class="native"/>
</id>
<property name="name" column="name" type="string"/>
<many-to-one name="type" class="com.atp.Model.TestCases.TestType" fetch="select">
<column name="idtestType"/>
</many-to-one>
<property name="data" column="data" type="binary"/>
<property name="creationDate" column="creationDate" type="string"/>
<property name="createdBy" column="createdBy" type="string"/>
</class>
</hibernate-mapping>
Model
public class TestType {
private int id;
private String desc;
private Set<TestCase> testCases = new HashSet<>(0);
public TestType() {
}
public TestType(String desc, Set<TestCase> testCases) {
this.desc = desc;
this.testCases = testCases;
}
TestType.xml
<hibernate-mapping>
<class name="com.atp.Model.TestCases.TestType" table="testType">
<meta attribute="class-description">
This class contains the testCases details.
</meta>
<id name="id" type="int" column="idtestType">
<generator class="native"/>
</id>
<property name="desc" column="desc" type="string"/>
<set name="testCases">
<key>
<column name="idtestType" />
</key>
<one-to-many class="com.atp.Model.TestCases.TestCase" />
</set>
</class>
</hibernate-mapping>
Trying to add it to the database
public static void addTestCase(String testName, String type, MultipartFile file, String createdBy) {
byte[] data;
Date date = new Date();
final DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
String creationDate = sdf.format(date);
TestType testType = new TestType();
testType.setDesc(type);
try {
data = file.getBytes();
TestCase testCase = new TestCase(testName,testType,data,creationDate,createdBy);
testType.getTestCases().add(testCase);
Database.addToDatabase(testCase);
} catch (IOException e) {
e.printStackTrace();
}
}
You're missing a
idtestType
column in the TestCase table.
Or, if you want to use the type column in the existing table your TestCase.xml-Mapping is wrong and should be
<many-to-one name="type" class="com.atp.Model.TestCases.TestType" fetch="select">
<column name="type"/>
</many-to-one>
(column is "type" instead of "idtestType")
I have the following structure in my database:
I've mapped them in hibernate configuration files like this:
<hibernate-mapping>
<class name="model.CartEntity" table="cart">
<id name="id" type="int" column="id">
<generator class="native" />
</id>
<set name="products" table="cart_product_record"
inverse="true" lazy="false" fetch="select" cascade="save-update, delete">
<key>
<column name="cart_id" not-null="false" />
</key>
<one-to-many class="model.ProductRecordEntity" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="model.ProductRecordEntity" table="product_record">
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<many-to-one name="product" class="model.ProductEntity" fetch="select" cascade="save-update, delete">
<column name="product_id" />
</many-to-one>
<many-to-one name="cart" class="model.CartEntity" fetch="select" cascade="save-update, delete">
<column name="cart_id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="model.ProductEntity" table="product">
<id name="id" type="int" column="id">
<generator class="native" />
</id>
<set name="productRecords" table="product_record_product" inverse="true"
lazy="false" fetch="select" cascade="save-update, delete">
<key>
<column name="product_id" not-null="true" />
</key>
<one-to-many class="model.ProductRecordEntity" />
</set>
</class>
</hibernate-mapping>
I retrieve from the database the cart which has all the product records, no problem so far, I get all the necessary data correctly.
CartEntity cart = findById(id);
List<ProductRecordEntity> productRecords = cart.getProductRecords();
The problem is when I try to get the product from the product record:
for (ProductRecordEntity productRecord: productRecords){
ProductEntity product = productRecord.getProduct();
}
I get an object with all fields with their default value, not the information from database.
When saving the entities in the database, the ids are populated correctly.
Product record table:
And the product table:
These are the entities:
public class CartEntity {
private int id;
private Set<ProductRecordEntity> products = new HashSet<ProductRecordEntity>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Set<ProductRecordEntity> getProducts() {
return products;
}
public void setProducts(Set<ProductRecordEntity> products) {
this.products = products;
}
}
public class ProductRecordEntity {
private int id;
private CartEntity cart;
private ProductEntity product;
public CartEntity getCart() {
return cart;
}
public void setCart(CartEntity cart) {
this.cart = cart;
}
public ProductEntity getProduct() {
return product;
}
public void setProduct(ProductEntity product) {
this.product = product;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
public class ProductEntity implements Serializable{
private int id;
private Set<ProductRecordEntity> productRecords;
public Set<ProductRecordEntity> getProductRecords() {
return productRecords;
}
public void setProductRecords(Set<ProductRecordEntity> productRecords) {
this.productRecords = productRecords;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
This is the order of operations on the database:
persist(cartEntity);
persist(productEntity);
productRecordEntity.setCartEntity(cartEntity);
cartEntity.getProducts().add(productRecordEntity);
productRecordEntity.setProduct(productEntity);
persist(productRecordEntity);
productEntity.getProductRecords().add(productRecordEntity);
update(productEntity);
update(cartEntity);
Any idea what I'm missing? I can't find where the problem is, I've double, triple checked everything.
for CartEntity and ProductEntity mapping, why are you using association tables? you should use table="product_record".
I fixed it by adding lazy="false" to the ProductOrder xml mapping.
<hibernate-mapping>
<class name="model.ProductOrderEntity" table="product_order">
<id name="id" type="int" column="product_order_id">
<generator class="native" />
</id>
<property name="quantity" column="quantity" type="int" />
<property name="price" column="price" type="java.lang.Float" />
<many-to-one name="product" class="model.ProductEntity"
fetch="select" lazy="false">
<column name="product_id" not-null="true" />
</many-to-one>
<many-to-one name="order" class="model.OrderEntity"
fetch="select" lazy="false">
<column name="order_id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
I think it's an initialization problem, when getting the product records from the database I should initialize the product field while the session is still opened, like this:
Hibernate.initialize(product);
I have a class called product here is the definition
public class Product {
private String productId;
private Set<Label> name;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public Set<Label> getName() {
return name;
}
public void setName(Set<Label> name) {
this.name = name;
}
}
i want the property called name to be retrieved via a select statement so I added this in my mapping file.
<class name="Product" table="PRODUCT">
<id name="productId" type="java.lang.String">
<column name="PRODUCTID" />
<generator class="assigned" />
</id>
<set name="name" cascade="all" inverse="true" lazy="false">
<key column="CONTENTID" />
<one-to-many class="com.dbs.web.models.org.Label" />
<loader query-ref="nameLabel" />
</set>
</class>
<sql-query name="nameLabel">
<load-collection alias="lbl" role="Product.name" />
SELECT {lbl.*} FROM LABEL lbl where lbl.CONTENTID = :productId and
lbl.KEY ='name'
</sql-query>
So all this works well. I am just a little worried that it would not perform very well. Its not like there will be thousands of record return by the sql-query it might be like 10.
Is there another way that this can be achieved.
i have try to use Hibernate with this class that include
ArrayList :
but i get this exception:
expected type: java.util.ArrayList, actual value: org.hibernate.collection.PersistentList
(i must use Arraylist because just List is't Serializable and it's make me trouble)
this exception throw when the jpa entitymanager start.
this is the class:
package Entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import msg.AnsMsg;
public class Person implements Serializable {
static final long serialVersionUID = 1L;
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
private String _email;
private ArrayList <AnsMsg> msgList=new ArrayList<AnsMsg>();
public ArrayList <AnsMsg> getMsgList() {
return msgList;
}
public void setMsgList(ArrayList <AnsMsg> msgList) {
this.msgList = msgList;
}
public Person(){}
public String getEmail() {
return _email;
}
public void set_email(String _email) {
this._email = _email;
}
}
this is the hbm 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 Apr 17, 2012 9:20:13 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="Entities.Person" table="PERSON">
<id name="id" type="long">
<column name="ID" />
<generator class="increment" />
</id>
<property name="_email" type="java.lang.String" access="field">
<column name="_EMAIL" />
</property>
<list name="msgList" inverse="false" table="ANSMSG" lazy="true">
<key>
<column name="ID" />
</key>
<list-index></list-index>
<one-to-many class="msg.AnsMsg" />
</list>
</class>
</hibernate-mapping>
how can i use java Arraylist with hibernate,
thanks in advance.
I think you need to associate the interface List and not the actual ArrayList class. If you see the PersistetList documentation http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/collection/PersistentList.html it implements java.util.List.
According to Hibernate Javadoc , PersistentList is also Serializable. Your POJO can have a reference to List, but in Runtime and instance of PersistentList -which is Serializable- should be used.
In a nutshell, just use List interface.