I am new to Hibernate (implementing since yesterday) and i succesfully created a method, that transfers my Customer Objects to the Database.
After i quit my application and start it again and create a new session (in an other method) based on my hibernate.cfg.xml file with this setting:
<property name="hibernate.hbm2ddl.auto">create</property>
It leads to that point, that all relevant tables, created with Hibernate are being deleted.
So maybe that is a comprehension question, but i think "transparent persistence by hibernate" means also, that my POJO's are persistent beyond the runtime of my application!?
So i read several topics on Stackoverflow and tried it with this setting:
<property name="hibernate.hbm2ddl.auto">update</property>
But this leads to SQL errors:
com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'
Of course i don't want have duplicates, so i suppose that hibernate doesn't send a SQL Statement referring to an existing object.
It sends a Statement like this:
UPDATE `customer` SET `id`=1,`birthday`='1990-10-05 00:00:00',`forename`='TestCustomer',`gender`='F',`generatedProfitsLastYear`='0',`generatedProfitsTotal`='0',`surename`='A',`gcid`='1'
But i need the same statement, with a
Where `id`=1
at the end.
So basically what i want is, that hibernate doesn't drop all the tables and creates it again when i restart my application and create a new session based on the configuration file. So after i open a new session, i can transfer the Customer Objects stored in the database to POJOs.
Did i understand the concept of hibernate incorrectly or am i making a typical beginners mistake?
Below you will find my Customer Class:
#Entity
#Table(name="CUSTOMER")
public class Customer {
private int id;
private String forename;
private String surname;
private char gender;
private Date birthday;
private double generatedProfitsTotal;
private double generatedProfitsLastYear;
private CustomerGroup assignedTo;
public Customer(int id, String forename, String surname, char gender,
Date birthday) {
super();
this.id = id;
this.forename = forename;
this.surname = surname;
this.gender = gender;
this.birthday = birthday;
}
#Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "forename")
public String getForename() {
return forename;
}
public void setForename(String forename) {
this.forename = forename;
}
#Column(name = "surename")
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
#Column(name = "gender")
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
#Column(name = "birthday")
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
#Column(name = "generatedProfitsTotal")
public double getGeneratedProfitsTotal() {
return generatedProfitsTotal;
}
public void setGeneratedProfitsTotal(double generatedProfitsTotal) {
this.generatedProfitsTotal = generatedProfitsTotal;
}
#Column(name = "generatedProfitsLastYear")
public double getGeneratedProfitsLastYear() {
return generatedProfitsLastYear;
}
public void setGeneratedProfitsLastYear(double generatedProfitsLastYear) {
this.generatedProfitsLastYear = generatedProfitsLastYear;
}
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="gcid", nullable=true, insertable=true, updatable=true)
public CustomerGroup getAssignedTo() {
return assignedTo;
}
public void setAssignedTo(CustomerGroup assignedTo) {
this.assignedTo = assignedTo;
}
}
my hibernate config file:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1/hibernatetesting</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="studyproject.Customer"/>
<mapping class="studyproject.CustomerGroup"/>
<mapping class="studyproject.BonusPackage"/>
</session-factory>
</hibernate-configuration>
Thanks
try session.saveOrUpdate() method where you have used session.save() it will prevent your database from dropping while fetching data use it with hbm2ddl.auto update. it worked for me. hope it helps.
What did you do where the 'duplicate error' occurs? Now I have the hibernate.hbm2ddl.auto configured as yours, but it's okay saving or updating entity in my local.
Related
After starting the program (launching TomCat) there are no tables created in the schema, but the table "player" has to be created automatically.
I checked hibernate config, but can't find where is the problem.
I've tried changing hbm2ddl.auto to hibernate.hbm2ddl.auto (also create, create-drop etc.) but it didn't help.
If there are any ideas, please let me know. Thanks.
Entity class:
package com.game.entity;
import javax.persistence.*;
import java.util.Date;
#Entity
#Table(schema = "rpg", name = "player")
public class Player {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name", length = 12, nullable = false)
private String name;
#Column(name = "title", length = 30, nullable = false)
private String title;
#Column(name = "race", nullable = false)
#Enumerated(EnumType.ORDINAL)
private Race race;
#Column(name = "profession", nullable = false)
#Enumerated(EnumType.ORDINAL)
private Profession profession;
#Column(name = "birthday", nullable = false)
private Date birthday;
#Column(name = "banned", nullable = false)
private Boolean banned;
#Column(name = "level", nullable = false)
private Integer level;
public Player() {
}
public Player(Long id, String name, String title, Race race, Profession profession, Date birthday, Boolean banned, Integer level) {
this.id = id;
this.name = name;
this.title = title;
this.race = race;
this.profession = profession;
this.birthday = birthday;
this.banned = banned;
this.level = level;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Race getRace() {
return race;
}
public void setRace(Race race) {
this.race = race;
}
public Profession getProfession() {
return profession;
}
public void setProfession(Profession profession) {
this.profession = profession;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Boolean getBanned() {
return banned;
}
public void setBanned(Boolean banned) {
this.banned = banned;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
}
Repository class:
package com.game.repository;
import com.game.entity.Player;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.NativeQuery;
import org.springframework.stereotype.Repository;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Optional;
#Repository(value = "db")
public class PlayerRepositoryDB implements IPlayerRepository {
private final SessionFactory sessionFactory;
public PlayerRepositoryDB() {
Configuration configuration = new Configuration().configure().addAnnotatedClass(Player.class);
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
#Override
public List<Player> getAll(int pageNumber, int pageSize) {
try(Session session = sessionFactory.openSession()){
NativeQuery<Player> nativeQuery = session.createNativeQuery("SELECT * FROM rpg.player", Player.class);
nativeQuery.setFirstResult(pageNumber * pageSize);
nativeQuery.setMaxResults(pageSize);
return nativeQuery.list();
}
}
Hibernate configuration:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/rpg</property>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">1234</property>
<property name="hbm2ddl.auto">update</property>
<property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
Full project code with pom.xml is available by link:
https://github.com/gamlethot/project-hibernate-1
1-Hibernate does not recognize your repository. You should not mark repo classes as #Repository because they are not interfaces and in your example they are working like a service. So they can be #Service.
2-Do not implement IPlayerRepository. Mark it as #Repository and just autowire it to your service classes (or use constructor injection and just use like a variable)
Like:
#Service
public class PlayerRepositoryDB {
private IPlayerRepository playerRepository;
public PlayerRepositoryDB (IPlayerRepository playerRepository){ //CONSTRUCTOR
this.playerRepository = playerRepository;...
3- DB repository classes are implementing IPlayerRepository but it must be marked as #Repository and It should extend either CrudRepository or JpaRepository (which extends CrudRepository already).
Like:
#Repository
public interface IPlayerRepository extends JpaRepository<Player, Long> {
//Here are the methods;
}
Here, the Long is the type of primary key of Player class.
Hibernate XML:
<property name="hibernate.connection.CharSet">utf8mb4</property>
<property name="hibernate.connection.characterEncoding">UTF-8</property>
<property name="hibernate.connection.useUnicode">true</property>
Connection url:
db.url=jdbc:mysql://localhost:3306/db_name?useUnicode=true&character_set_server=utf8mb4
As a side note I would like to make one clarification that UTF-8 is the character encoding while utf8mb4 is a character set that MySQL supports. MySQL's utf8mb4 is a superset to MySQL's utf8.
Spring/Hibernate filter:
<form accept-charset="UTF-8">
Problem solved.
It was because of javax.persistence.; import instead of
jakarta.persistence. in entity class.
I have created a PostgreSQL script just to insert a row in the customer table. The insert happens when my project is starting to run.
But it doesn't work because I'm getting the following error:
[EL Warning]: 2016-10-23 22:14:40.182--ServerSession(609762439)--?>Exception [EclipseLink-4002] (Eclipse Persistence Services - >2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax >error at end of input
Position: 82 Error Code: 0 Call: INSERT INTO customer (id, Name, Adres, PostalCode, City, Tel, >Fax, Number) VALUES Query: DataModifyQuery(sql="INSERT INTO customer (id, Name, Adres, >PostalCode, City, Tel, Fax, Number) VALUES") [EL Warning]: 2016-10-23 22:14:40.183--ServerSession(609762439)-->Exception [EclipseLink-4002] (Eclipse Persistence Services - >2.5.2.v20140319-9ad6abd): >org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: syntax >error at or near "1"
Position: 2 Error Code: 0 Call: (1, 'Kantoor Snel Transport / Distributiecentrum', >'Zeugstraat', '2801JD', 'Gouda', 182512784, NULL, '92'); Query: DataModifyQuery(sql="(1, 'Kantoor Snel Transport / >Distributiecentrum', 'Zeugstraat', '2801JD', 'Gouda', 182512784, NULL, >'92');") [EL Info]: connection: 2016-10-23 22:15:02.917-->ServerSession(609762439)-->file:/C:/Users/yomac_000/workspace/.metadata/.plugins/org.eclipse.wst.ser>ver.core/tmp0/wtpwebapps/snel-transport/WEB-INF/classes/_snel-transport >logout successful
Here is the persistence.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
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_2_1.xsd">
<persistence-unit name="snel-transport" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>nl.cimsolutions.snel_transport.models.Orders</class>
<class>nl.cimsolutions.snel_transport.models.OrderLine</class>
<class>nl.cimsolutions.snel_transport.models.OrderList</class>
<class>nl.cimsolutions.snel_transport.models.Customer</class>
<class>nl.cimsolutions.snel_transport.models.Product</class>
<class>nl.cimsolutions.snel_transport.models.Category</class>
<class>nl.cimsolutions.snel_transport.models.Status</class>
<class>nl.cimsolutions.snel_transport.models.Truck</class>
<!-- <jta-data-source>java:app/snel-transport</jta-data-source> -->
<!-- <exclude-unlisted-classes>false</exclude-unlisted-classes> -->
<properties>
<property
name="javax.persistence.schema-generation.database.action"
value="drop-and-create" />
<property name="eclipselink.canonicalmodel.subpackage"
value="dev" />
<property name="javax.persistence.sql-load-script-source"
value="META-INF/sql/Customer2.sql" />
<property name="javax.persistence.schema-generation-target"
value="database" />
<property name="javax.persistence.jdbc.driver"
value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://localhost:5432/snel-transport" />
<property name="javax.persistence.jdbc.user" value="transport_user" />
<property name="javax.persistence.jdbc.password"
value="admin" />
<property name="javax.persistence.jdbc.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
And here is my PostgreSQL script:
INSERT INTO customer (id, Name, Adres, PostalCode, City, Tel, Fax, Number) VALUES
(1, 'Kantoor Snel Transport / Distributiecentrum', 'Zeugstraat', '2801JD', 'Gouda', 182512784, NULL, '92');
And here is how the Customer model looks like:
#Entity
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#TableGenerator(
name = "CustomerGenerator",
allocationSize = 1,
initialValue = 1)
#Id
#GeneratedValue(strategy = GenerationType.TABLE,
generator="CustomerGenerator")
private Long id;
private String name;
private String adres;
#Column(name="Number")
private String streetNumber;
#Column(name="PostalCode")
private String postalCode;
#Column(name="City")
private String city;
#Column(name="Tel")
private String tel;
#Column(name="Fax")
private String fax;
#OneToMany(mappedBy = "customer", targetEntity = Orders.class)
private List<Orders> orders;
public Customer() {
// TODO Auto-generated constructor stub
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStreetNumber() {
return streetNumber;
}
public void setStreetNumber(String streetNumber) {
this.streetNumber = streetNumber;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public String toString() {
return "model.OrderLine[ id=" + id + " ]";
}
public String getName() {
return name;
}
public String getAdres() {
return adres;
}
public void setName(String name) {
this.name = name;
}
public void setAdres(String adres) {
this.adres = adres;
}
}
I have already tried using the PostgreSQL script in pgAdmin. And there the script works, but somehow it doesn't work in JPA.. Anyone got a clue how I can solve this problem?
I spent the whole day to solve this problem. An error occurs on line with session.getTransaction().commit();
private SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
#Override
public void initGroup(Group group) throws BotException {
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
session.persist(group);
session.getTransaction().commit();
} catch (PersistenceException e)
{
throw new BotException("You are already registred");
}
finally {
session.close();
sessionFactory.close();
}
Surprisingly, I have the same function for "Station" entity, but it works fine
It's strange so much. I don't know how to solve it.
It's my Group.class
#Entity
#Table(name = "group")
public class Group {
private String name;
private String password;
private String telegramId;
private int experience;
private int money;
private String nowStation;
public Group() {}
public Group(String name, String password, String telegramId) {
this.name = name;
this.password = password;
this.telegramId = telegramId;
}
#Id
#Column(name = "name", nullable = false, length = 45)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "password", nullable = false, length = 45)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Basic
#Column(name = "telegram_id", nullable = false, length = 45)
public String getTelegramId() {
return telegramId;
}
public void setTelegramId(String telegramId) {
this.telegramId = telegramId;
}
#Basic
#Column(name = "experience", nullable = true)
public int getExperience() {
return experience;
}
public void setExperience(int experience) {
this.experience = experience;
}
#Basic
#Column(name = "money", nullable = true)
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
#Basic
#Column(name = "now_station", nullable = true, length = 45)
public String getNowStation() {
return nowStation;
}
public void setNowStation(String nowStation) {
this.nowStation = nowStation;
}
and hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/game_data_base</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.username">root</property>
<property name="connection.password">*******</property>
<mapping class="model.Group"/>
<mapping class="model.Station"/>
<mapping class="model.User"/>
<!-- DB schema will be updated if needed -->
<!-- <property name="hbm2ddl.auto">update</property> -->
</session-factory>
</hibernate-configuration>
Errors
сен 25, 2016 7:42:54 PM org.telegram.telegrambots.logging.BotLogger severe
19:42:54.374 [PMPUTestBot Telegram Executor] DEBUG org.hibernate.service.internal.AbstractServiceRegistryImpl - Implicitly destroying ServiceRegistry on de-registration of all child ServiceRegistries
SEVERE: BOTSESSION
19:42:54.374 [PMPUTestBot Telegram Executor] INFO org.hibernate.orm.connections.pooling - HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/game_data_base]
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement
19:42:54.374 [PMPUTestBot Telegram Executor] DEBUG org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl - Implicitly destroying Boot-strap registry on de-registration of all child ServiceRegistries
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:147)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1411)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:475)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3168)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2382)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)
at dao.GroupDaoImpl.initGroup(GroupDaoImpl.java:32)
Thank you :)
Group is an SQL keyword. Rename your table to something else
#Table(name = "my_group")
I create this hql in my project (an snack bar), to search all orders that have the product selected by the user as parameter:
select order from Order order, OrderItem item
inner join order.cod_order_item as item
inner join item.cod_product as cod_product
where cod_product = id
However, when I run the createQuery(), gives a nullpointer at org.hibernate.hql.ast.HqlSqlWalker.createFromJoinElement.
What am i doing wrong?
Below, here's my codes:
OrderDAO.java
public class OrderDAO {
private Session session;
public PedidoDAO(Session session){
this.session = session;
}
public List<Order> getAllOrderFromProduct(Product product{
String hql = "select order from Order order, OrderItem item " +
"inner join order.order_item_id as item " +
"inner join item.product_id as product_id " +
"where product_id = '"+ product.getId() + "'";
Configuration cfg = new Configuration();
SessionFactory factory = cfg.configure().buildSessionFactory();
Session session = factory.openSession();
Query query = session.createQuery(hql);
List result = query.list();
return result;
}
}
Order.java (entity)
#Entity
public class Order{
#Id
#GeneratedValue
private Long order_id;
#Column(name="order_date", nullable=false, length=15)
private Date data;
#Column(name="order_total", nullable=false, length=8)
private double total;
/* Relacionamentos */
#Column(name="employee_id", nullable=false, length=8)
private Long employee_id;
#Column(name="customer_id", nullable=false, length=8)
private Long customer_id;
#Column(name="order_item_id", nullable=false, length=8)
private Long order_item_id;
public Long getId() {
return order_id;
}
public void setId(Long order_id) {
this.order_id= order_id;
}
public Date getOrderDate() {
return order_date;
}
public void setOrderDate(Date order_date) {
this.order_date = order_date;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
public Long getFuncionario() {
return cod_funcionario;
}
public void setEmployee(Long employee_id) {
this.employee_id= employee_id;
}
public Long getCustomer() {
return customer_id;
}
public void setCustomer(Long customer_id) {
this.customer_id= customer_id;
}
public Long getOrderItem() {
return order_item_id;
}
public void setOrderItem(Long order_item_id) {
this.order_item_id= order_item_id;
}
}
My hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/lanchonete_db</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- this will show us all sql statements -->
<property name="hibernate.show_sql">true</property>
<!-- mapping files -->
<mapping class="gigabyte.bean.Customer" />
<mapping class="gigabyte.bean.Address"/>
<mapping class="gigabyte.bean.Employee" />
<mapping class="gigabyte.bean.Order"/>
<mapping class="gigabyte.bean.OrderItem" />
<mapping class="gigabyte.bean.Product"/>
<mapping class="gigabyte.bean.Phone" />
</session-factory>
</hibernate-configuration>
Any help is welcome.
I found my error! I forgot to reference the annotation #ManyToMany in relationship table on Order.java, then the Hibernate tried to get the relationship between the two tables and found nothing. Now, works fine with this query, based on #axtavt answer:
select order from Order order, OrderItem item
inner join order.order_item as item
where item.cod_product = id
My Order.java corrected:
#Entity
public class Order{
#Id
#GeneratedValue
private Long order_id;
#Column(name="order_date", nullable=false, length=15)
private Date data;
#Column(name="order_total", nullable=false, length=8)
private double total;
/* Relationships*/
#Column(name="employee_id", nullable=false, length=8)
private Long employee_id;
#Column(name="customer_id", nullable=false, length=8)
private Long customer_id;
#ManyToMany(targetEntity=OrderItem.class, fetch=FetchType.LAZY)
#Fetch(FetchMode.SUBSELECT)
#JoinTable(name = "order_order_item", joinColumns = { #JoinColumn(name = "cod_order") },
inverseJoinColumns = { #JoinColumn(name = "cod_item") })
public Set<OrderItem> setOrderItem = new HashSet<OrderItem>();
public Long getId() {
return order_id;
}
public void setId(Long order_id) {
this.order_id= order_id;
}
public Date getOrderDate() {
return order_date;
}
public void setOrderDate(Date order_date) {
this.order_date = order_date;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
public Long getFuncionario() {
return cod_funcionario;
}
public void setEmployee(Long employee_id) {
this.employee_id= employee_id;
}
public Long getCustomer() {
return customer_id;
}
public void setCustomer(Long customer_id) {
this.customer_id= customer_id;
}
public Set<OrderItem> getOrderItem() {
return orderItem;
}
public void setOrderItem(Set<OrderItem> orderItem) {
this.orderItem= orderItem;
}
}
You certainly don't need to add OrderItem to from explicitly since it's already added by join:
select order from Order order
inner join order.cod_order_item as item
inner join item.cod_product as cod_product
where cod_product = id
I can't figure out what the problem is, please help. I've searched a lot, but didn't find any useful advice. Maybe you can help me. Thanks a lot.
There are two classes using eclipselink as jpa provider:
#Entity
#Table(name = "USER")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
private String login;
private Long groupId;
private String email;
#ManyToMany(mappedBy = "users")
private List polls;
#OneToMany(mappedBy = "user")
private List votes;
public List getVotes() {
return votes;
}
public void setVotes(List votes) {
this.votes = votes;
}
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public Long getGroupId() {
return groupId;
}
public void setGroupId(Long groupId) {
this.groupId = groupId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List getPolls() {
return polls;
}
public void setPolls(List polls) {
this.polls = polls;
}
}
and
#Entity
#Table(name = "VOTE")
public class Vote {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private Long vid;
private String comment;
#ManyToOne
private User user;
#ManyToOne
private Option option;
public Vote() {
}
public Long getVid() {
return vid;
}
public void setVid(Long vid) {
this.vid = vid;
}
#Column(name = "comment")
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Option getOption() {
return option;
}
public void setOption(Option option) {
this.option = option;
}
}
When I'm trying to compile this, I receive error:
Exception [EclipseLink-7214] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The target entity of the relationship attribute [votes] on the class [class logic.User] cannot be determined. When not using generics, ensure the target entity is defined on the relationship mapping.
Here is my persistence.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="pollsPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>logic.Option</class>
<class>logic.Poll</class>
<class>logic.User</class>
<class>logic.Vote</class>
<class>logic.Greeting</class>
<properties>
<property name="eclipselink.jdbc.password" value="" />
<property name="eclipselink.jdbc.user" value="" />
<property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="eclipselink.jdbc.url"
value="jdbc:mysql://localhost:3306/core_polls" />
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.logging.level" value="INFO" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
</properties>
</persistence-unit>
</persistence>
As stated in the Javadoc
If the collection is defined using generics to specify the element
type, the associated target entity type need not be specified;
otherwise the target entity class must be specified.
So, you can do either
#OneToMany(mappedBy = "user")
private List<Vote> votes;
or
#OneToMany(targetEntity=logic.Vote.class, mappedBy = "user")
private List votes;
But I would prefer the first.