Hibernate relationship code - spring

Getting following error while executing the Hibernate program for a relationship:
Exception in thread "main" org.hibernate.MappingException: Could not determine type for: com.Employee.Department.Department, at table: Employee, for columns: [org.hibernate.mapping.Column(dept)]
The code is shown in below:
Employee.java: Contains the 1-M relationship
package com.Employee.Employee;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.Employee.Department.Department;
#Entity
#Table(name = "Employee_1toMany")
public class Employee {
#Id
#GeneratedValue
#Column(name = "EId")
private int emp_id;
#Column(name = "EName")
private String name;
private Department dept;
public int getEmp_id() {
return emp_id;
}
public void setEmp_id(int emp_id) {
this.emp_id = emp_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#ManyToOne
#JoinColumn(name = "DepartmentID")
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
}
Department.java: Contains M to 1 relationship
package com.Employee.Department;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import com.Employee.Employee.Employee;
#Entity
#Table(name = "Department_1toMany")
public class Department {
#Id
#GeneratedValue
#Column(name = "DId")
private int Dept_id;
#Column(name = "DName")
private String Dept_name;
private List<Employee> emp;
public int getDept_id() {
return Dept_id;
}
public void setDept_id(int dept_id) {
Dept_id = dept_id;
}
public String getDept_name() {
return Dept_name;
}
public void setDept_name(String dept_name) {
Dept_name = dept_name;
}
#OneToMany(targetEntity = Employee.class, mappedBy = "dept", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public List<Employee> getEmp() {
return emp;
}
public void setEmp(List<Employee> emp) {
this.emp = emp;
}
}
MainClass.java:
package com.Employee.MainClass;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.Employee.Department.Department;
import com.Employee.Employee.Employee;
public class MainApp {
public static void main(String[] args) {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Department dept = new Department();
dept.setDept_name("Modern College");
Employee emp1 = new Employee();
emp1.setName("Rakesh");
Employee emp2 = new Employee();
emp2.setName("Sagar");
emp1.setDept(dept);
emp2.setDept(dept);
session.save(dept);
session.save(emp1);
session.save(emp2);
tx.commit();
}
}
hibernate.cfg.xml: This is the configuration class
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/EMP_PRACTISE</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="hibernate.show_sql">true</property>
<mapping class="com.Employee.Department.Department"></mapping>
<mapping class="com.Employee.Employee.Employee"></mapping>
</session-factory>
</hibernate-configuration>
Exception in detail:
Exception in thread "main" org.hibernate.MappingException: Could not determine type for: com.Employee.Department.Department, at table: Employee, for columns: [org.hibernate.mapping.Column(dept)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:455)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:422)
at org.hibernate.mapping.Property.isValid(Property.java:226)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:597)
at org.hibernate.mapping.RootClass.validate(RootClass.java:265)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:451)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
at com.Employee.MainClass.MainApp.main(MainApp.java:13)

I believe you cannot mix fields and getter methods annotations. Place them to corresponding fields.
Employee.java
#ManyToOne
#JoinColumn(name = "DepartmentID")
private Department dept;
// mapping annotation on the field
public Department getDept() {
return dept;
}
Department.java
#OneToMany(targetEntity = Employee.class, mappedBy = "dept", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Employee> emp;
// mapping annotation on the field
public List<Employee> getEmp() {
return emp;
}

Related

hibernate & spring, invalid identifier

I have stuck on dealing with DB by using hibernate orm in spring mvc environment.
I have some tables; but I'm not gonna tell you my tables(If you want, I will edit this post)
The problem is that when hibernate runs, it generates sql - I can see the sql by configuring "hbm2_ddl auto" - but the sql has invalid identifier.
select newsreplie0_.news_article# as news6_3_4_, newsreplie0_.reply# as reply1_4_,
newsreplie0_.reply# as reply1_4_3_, newsreplie0_.account_account# as account5_4_3_,
newsreplie0_.content as content4_3_, newsreplie0_.dt as dt4_3_,
newsreplie0_.news_article# as news6_4_3_, newsreplie0_.reply_at as reply4_4_3_,
account1_.account# as account1_0_0_, account1_.email as email0_0_,
account1_.passwd as passwd0_0_, accountpro2_.account# as account1_1_1_,
accountpro2_.nickname as nickname1_1_, accountsec3_.account# as account1_2_2_,
accountsec3_.activate_key as activate2_2_2_, accountsec3_.activated as activated2_2_,
accountsec3_.enabled as enabled2_2_, accountsec3_.login_failed as login5_2_2_
from news_reply newsreplie0_
left outer join
cookingstep.account account1_ on newsreplie0_.account_account#=account1_.account#
left outer join
cookingstep.account_profile accountpro2_ on account1_.account#=accountpro2_.account#
left outer join
cookingstep.account_security accountsec3_ on account1_.account#=accountsec3_.account#
where newsreplie0_.news_article#=9
{FAILED after 4 msec}
The above statement is a sql generated by hibernate. And the error is:
java.sql.SQLSyntaxErrorException:
ORA-00904: "NEWSREPLIE0_"."ACCOUNT_ACCOUNT#": Invalid Identifier
In that exception message, there is a column called "ACCOUNT_ACCOUNT#".
It should be just "ACCOUNT#", not following "ACCOUNT_".
So, how to remove the word ?
EDIT:
Thank you all for your reply. I have asked similar question before.
And I checked out that article, it seems the problem was #JoinColumn annotation missing. Now it works out.
Here is my Entities.
Account.java for user information
package com.musicovery12.cookingstep.persistence.model;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
#Entity
#Table(name="account", catalog="cookingstep", uniqueConstraints= {
#UniqueConstraint(columnNames="email")
})
public class Account implements Serializable{
private static final long serialVersionUID = 1L;
private int accountId;
private String email;
private String password;
private Set<UserRole> userRoles = new HashSet<UserRole>(0);
private AccountProfile profile;
private AccountSecurity security;
private Set<News> newsList;
private Set<NewsReply> newsReplyList;
public Account() {}
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_account")
#SequenceGenerator(name="seq_account", sequenceName="seq_account", allocationSize=1)
#Column(name="account#", unique=true, nullable=false)
public int getAccountId() {
return accountId;
}
public void setAccountId(int accountId) {
this.accountId = accountId;
}
#Column(name="email", unique=true, nullable=false)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name="passwd", nullable=false)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#OneToMany(mappedBy="pk.account", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
#OneToOne(mappedBy="account", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
public AccountProfile getProfile() {
return profile;
}
public void setProfile(AccountProfile profile) {
this.profile = profile;
}
#OneToOne(mappedBy="account", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
public AccountSecurity getSecurity() {
return security;
}
public void setSecurity(AccountSecurity security) {
this.security = security;
}
#OneToMany(mappedBy="account", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
public Set<News> getNewsList() {
return newsList;
}
public void setNewsList(Set<News> newsList) {
this.newsList = newsList;
}
#OneToMany(mappedBy="account", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
public Set<NewsReply> getNewsReplyList() {
return newsReplyList;
}
public void setNewsReplyList(Set<NewsReply> newsReplyList) {
this.newsReplyList = newsReplyList;
}
}
and NewsReply.java for news community article's reply list.
package com.musicovery12.cookingstep.persistence.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
#Table(name="news_reply")
public class NewsReply {
private int replyId;
private News news;
private Date date;
private String content;
private Account account;
private int replyAt;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="gen_seq")
#SequenceGenerator(name="gen_seq", sequenceName="gen_seq", allocationSize=1)
#Column(name="reply#", unique=true, nullable=false)
public int getReplyId() {
return replyId;
}
public void setReplyId(int replyId) {
this.replyId = replyId;
}
#Temporal(TemporalType.DATE)
#Column(name="dt")
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
#Column(name="content", nullable=false)
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
#Column(name="reply_at")
public int getReplyAt() {
return replyAt;
}
public void setReplyAt(int replyAt) {
this.replyAt = replyAt;
}
#ManyToOne
public News getNews() {
return news;
}
public void setNews(News news) {
this.news = news;
}
#ManyToOne
#JoinColumn(name="account#", referencedColumnName="account#")
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}
in NewsReply.java, there was no JoinColumn annotation to point foreing key column name.
Thank you.
#ManyToOne
#JoinColumn(name="account#", referencedColumnName="account#")
public Account getAccount() {
return account;
}
This is the problem, you tell hibernate the table has a technical name of account# what is not allowed.
What you can do is to force hibernate to use that # by defining
#ManyToOne
#JoinColumn(name="`account#`", referencedColumnName="`account#`")
public Account getAccount() {
return account;
}
But this is bad style and you have to do it on the owning-side too.
Why dont you let hibernate create the entitys for you? He is much more precisly!

Hibernate Query to join two table using Jparepository

Hi all i have a small issue with joining two tables using jparepository using #query but i am getting error. please help me with this.
UserAddress.java
package com.surya_spring.example.Model;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
#Entity
#Table(name = "user_address")
//#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class UserAddress implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3570928575182329616L;
/*#ManyToMany(cascade = {CascadeType.ALL},fetch=FetchType.EAGER,mappedBy = "userAddress",targetEntity=UserData.class)*/
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="user_id")
private UserData userdata;
#Id
#Column(name = "addr_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long addrid;
#Column(name = "dr_no")
#NotNull
private String doorNo;
#Column(name = "strt_name")
#NotNull
private String streetName;
#Column(name = "city")
#NotNull
private String city;
#Column(name = "country")
#NotNull
private String country;
/*#OneToOne(cascade=CascadeType.ALL)
#Column(name="user_id")*/
public UserData getUserdata() {
return userdata;
}
public void setUserdata(UserData userdata) {
this.userdata = userdata;
}
public Long getAddrid() {
return addrid;
}
public void setAddrid(Long addrid) {
this.addrid = addrid;
}
public String getDoorNo() {
return doorNo;
}
public void setDoorNo(String doorNo) {
this.doorNo = doorNo;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
this.streetName = streetName;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
UserData.java
package com.surya_spring.example.Model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.NonNull;
#Entity
#Table(name = "user_data")
public class UserData implements Serializable{
/**
* Serialization ID
*/
private static final long serialVersionUID = 8133309714576433031L;
/*#ManyToMany(targetEntity=UserAddress.class ,cascade= {CascadeType.ALL },fetch=FetchType.EAGER)
#JoinTable(name="userdata",joinColumns= #JoinColumn(name="userid"),inverseJoinColumns = #JoinColumn(name="userid"))
*/
#Id
#Column(name = "user_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
#Column(name = "user_name")
#NonNull
private String userName;
#Column(name = "user_email")
#NonNull
private String userEmail;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
}
Repository:
package com.surya_spring.example.Repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.surya_spring.example.Model.UserData;
public interface UserDataRepository extends JpaRepository<UserData, Long>{
#Query(" FROM UserData where userId= :id")
public List<UserData> findBySearchTerm(#Param("id") Long id);
}
any one let me know the query to join this both the table to get city name from user_address where user_id=? joining user_data table
If you want to get the city for a user you can do:
#Query("SELECT ua.city FROM UserAddress ua WHERE ua.userdata.userId = ?1")
String findCityByUserId(Long userId);
Note that your entity names are used (like in your java classes) and not the table names in database! You do not have to do the join by yourself as you can use the properties of your domain models to access the related data

I want to fetch my product details in database but it throws excepion org.hibernate.hql.internal.ast.QuerySyntaxException: Product is not mapped

I'm keep getting an exception. I've tried to solve this problem for a few days now...
Please help me...
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.hql.internal.ast.QuerySyntaxException: Product is not mapped [from Product]
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
This is my ProductController
package com.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.model.Categories;
import com.model.Product;
import com.service.ProductService;
#Controller
public class ProductController {
#Autowired
private ProductService productService;
// Getters and Setters
public ProductService getProductService() {
return productService;
}
public void setProductService(ProductService productService) {
this.productService = productService;
}
// Request Mapping
#RequestMapping("/getAllProducts")
public ModelAndView getAllProducts() {
List<Product> products = productService.getAllProducts();
return new ModelAndView("productList", "products", products);
}
#RequestMapping("getProductById/{productId}")
public ModelAndView getProductById(#PathVariable(value = "productId") String productId) {
Product product = productService.getProductById(productId);
return new ModelAndView("productPage", "productObj", product);
}
#RequestMapping("/delete/{productId}")
public String deleteProduct(#PathVariable(value = "productId") String productId) {
productService.deleteProduct(productId);
return "redirect:/getAllProducts";
}
#RequestMapping(value = "/admin/product/addProduct", method = RequestMethod.GET)
public String getProductForm(Model model) {
Product product = new Product();
Categories category = new Categories();
category.setCategoryId("1");
product.setProductCategory(category);
model.addAttribute("productFormObj", product);
return "productForm";
}
#RequestMapping(value = "/admin/product/addProduct", method = RequestMethod.POST)
public String addProduct(#ModelAttribute(value = "productFormObj") Product product) {
productService.addProduct(product);
return "redirect:/getAllProducts";
}
}
This is my ProductClass
package com.model;
import java.util.Locale.Category;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "product")
public class Product {
#Id
#Column
#GeneratedValue(strategy = GenerationType.AUTO)
private String productId;
#Column
private String productDescription;
#Column
private String productManufacturer;
#Column
private String productName;
#Column
private double productPrice;
#Column(name="stockunit")
private String unitStock;
#ManyToOne
#JoinColumn(name="categoryId")
private Categories productCategory;
// Getters and Setter
public String getProductId() {
return productId;
}
public Categories getProductCategory() {
return productCategory;
}
public String getProductDescription() {
return productDescription;
}
public String getProductManufacturer() {
return productManufacturer;
}
public String getProductName() {
return productName;
}
public double getProductPrice() {
return productPrice;
}
public String getUnitStock() {
return unitStock;
}
public void setProductId(String productId) {
this.productId = productId;
}
public void setProductCategory(Categories category) {
this.productCategory = category;
}
public void setProductDescription(String productDescription) {
this.productDescription = productDescription;
}
public void setProductManufacturer(String productManufacturer) {
this.productManufacturer = productManufacturer;
}
public void setProductName(String productName) {
this.productName = productName;
}
public void setProductPrice(double productPrice) {
this.productPrice = productPrice;
}
public void setUnitStock(String unitStock) {
this.unitStock = unitStock;
}
//Constructors
public Product(String productId, Categories productCategory, String productDescription, String productManufacturer,
String productName, double productPrice, String unitStock) {
super();
this.productId = productId;
this.productCategory = productCategory;
this.productDescription = productDescription;
this.productManufacturer = productManufacturer;
this.productName = productName;
this.productPrice = productPrice;
this.unitStock = unitStock;
}
public Product(){
}
}
This is my application Context
<!-- for Entity Classes annotated Classes package -->
<property name="packagesToScan">
<list>
<value>com.model.Product</value>
<value>com.model.Categories</value>
</list>
</property>
</bean>
My Category Class
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "categories")
public class Categories {
#Id
private String categoryId;
#Column
private String Categories;
#OneToMany(mappedBy = "categories")
private List<Product> product;
//And Respective Getters and Setters
ProductList page
<tbody>
<c:forEach items="${products}" var="prod">
<tr>
<td>${prod.productId}</td>
<td>${prod.productCategory}</td>
<td>${prod.productName}</td>
<td>${prod.productPrice}</td>
<td>${prod.unitStock}</td>
<td>${prod.productDescription}</td>
<td>${prod.productManufacturer}</td>
<td>
<span class="glyphicon glyphicon-info"></span>
<span class="glyphicon glyphicon-trash"></span>
</td>
</tr>
</c:forEach>
After a long analyse i have found the solution for this problem
I have modified some code in my daoImpl.
this is older code.
List<Product> products = session.createQuery("from Product").list();
I have changed this to
List<Product> products = session.createCriteria(Product.class).list();
And some changes in appication Context as #v.ladynev said :
<property name="packagesToScan">
<list>
<value>com.model</value>
</list>
</property>
You should specify a package here, not classes
<property name="packagesToScan">
<list>
<value>com.model</value>
</list>
</property>

Hibernate Error Invalid Column Name

I am trying to make a one to many and many to one relation in hibernate and spring.
below is my code for product class
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="Product")
public class Product implements Serializable{
#Id
#Column(name="productId")
#GeneratedValue
private Integer productId;
#Column(name="productName")
private String productName;
#Column(name="productPrice")
private int productPrice;
//---------------------------------------item mapped to category------------------------------------------//
#ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinTable(
name="CategoryProduct",
joinColumns= #JoinColumn(name="productId")
)
private Category category;
//--------------------------------------------------------------------------------------------------------//
public Integer getProductId() {
return productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public int getProductPrice() {
return productPrice;
}
public void setProductPrice(int productPrice) {
this.productPrice = productPrice;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}
below is my code for category class
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.io.Serializable;
#Entity
#Table(name="Category")
public class Category implements Serializable{
#Id
#Column(name="categoryId")
#GeneratedValue
private Integer categoryId;
#Column(name="categoryName")
private String categoryName;
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinTable(
name="CategoryProduct",
joinColumns = #JoinColumn(name="categoryId"),
inverseJoinColumns = #JoinColumn(name="productId")
)
public Set<Product> product;
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public Set<Product> getProduct() {
return product;
}
public void setProduct(Set<Product> product) {
this.product = product;
}
}
Whenever i run the code i am getting Invalid column name 'category_categoryId'.
Structure of my tables
Product has column as productId, poductName and productPrice
category has columns as categoryId, categoryName
categoryproducts has columns as categoryId and productId
you forgot to put inverseJoinColumns at your #JoinTable in Product Class. This cause hibernate to use their convention of joinTable which is <ClassName>_<columnName>. Change it to
#JoinTable(
name="CategoryProduct",
joinColumns = #JoinColumn(name="productId"),
inverseJoinColumns = #JoinColumn(name="categoryId")
)
private Category category;
However, seeing at your design, you are actually creating 2 uni-directional association between product and category. If you want to create bi-directional association, I suggest you change the One side (Category), to use mappedBy
#OneToMany(mappedBy="category", cascade=CascadeType.ALL,fetch=FetchType.EAGER)
public Set<Product> product;
It will generally achieve the same result. Hope it helps!

Can't persist entity with child entity (#OneToOne relationship) using gwt requestfactory because of getting NullPointerException

I'm using GWT RequestFactory + Hibernate + Spring in my web app.
I have Principal and Profile entities that relate to each other as one to one. They share the same primary key.
On a client side I write such a code, which causes NullPointerException:
If I exclude "principal.setProfile(profile);" code line, principal entity will be stored successfully. I can't figure out why profile entity can't be stored along with principal.
Any suggestions will be highly appreciated. Thanks in advance!
public RegistrationPanel() {
TarantulaFactory factory = GWT.create(TarantulaFactory.class);
factory.initialize(new SimpleEventBus());
PrincipalRequestContext principalCtx = factory.createPrincipalRequest();
ProfileRequestContext profileCtx = factory.createProfileRequest();
PrincipalProxy principal = principalCtx.create(PrincipalProxy.class);
principal.setLogin("Billy");
principal.setPassword("Corgan");
ProfileProxy profile = profileCtx.create(ProfileProxy.class);
profile.setNickname("A");
profile.setName("b");
profile.setEmail("ABCD34#gmail.com");
profile.setBirthDate(new Date());
profile.setCurrentLocation("Chicago");
principal.setProfile(profile);
profile.setPrincipal(principal);
principalCtx.save(principal).fire();
}
Stack trace:
//------------------------------------------------------------------------
21:09:24.992 [ERROR] [application] Uncaught exception escaped
java.lang.NullPointerException: null
at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$MyConstraintViolation.<init>(AbstractRequestContext.java:434)
at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$StandardPayloadDialect.processPayload(AbstractRequestContext.java:366)
at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$5.onTransportSuccess(AbstractRequestContext.java:1151)
at com.google.web.bindery.requestfactory.gwt.client.DefaultRequestTransport$1.onResponseReceived(DefaultRequestTransport.java:136)
at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:258)
at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:412)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:338)
at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:219)
at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:571)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:279)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:242)
at sun.reflect.GeneratedMethodAccessor35.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
at java.lang.Thread.run(Thread.java:722)
//------------------------------------------------------------------------
Below is the source code for entities, proxies and RequestFactory.
Here are entity classes:
Profile.java
package com.szybieka.tarantula.core.domain;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
/**
*
* A Profile representing the user profile entity. Each user has single profile.
* Profile and {#link Principal} entities relate to each other as one-to-one.
* Shared primary key is used to join corresponding tables.
*
* #author Zmicer Szybieka
*
*/
#Entity
#Table(name = "profile", uniqueConstraints = { #UniqueConstraint(
columnNames = "id") })
public class Profile {
#Id
#NotNull
#Column(name = "id", unique = true)
#GeneratedValue(generator = "gen")
#GenericGenerator(name = "gen", strategy = "foreign",
parameters = #Parameter(name = "property", value = "principal"))
private Long id;
#Length(min = 1, max = 30)
private String nickname;
#Length(max = 30)
private String name;
#Column(name = "birth_date")
private Date birthDate; // date of birth, e.g. "20.01.1985"
#Length(max = 30)
#Column(name = "current_location")
private String currentLocation; // current location city, e.g. "NYC"
#Email
private String email;
private Date version;
#OneToOne(mappedBy = "profile", cascade = CascadeType.ALL)
private Principal principal; // the user principal corresponding to the
// profile
public Profile() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// omit setters/getters
}
Principal.java
package com.szybieka.tarantula.core.domain;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.validator.constraints.Length;
/**
* A Principal representing an identity used to determine access rights to
* application. Principal relates to {#link Profile} entity as one-to-one.
* Shared primary key is used to join corresponding tables.
*
* #author Zmicer Szybieka
*
*/
#Entity
#Table(name = "principal", uniqueConstraints = { #UniqueConstraint(
columnNames = "id") })
public class Principal {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Length(max = 20)
private String login;
#Length(max = 10)
private String password;
private Date version;
#OneToOne(cascade = CascadeType.ALL)
#PrimaryKeyJoinColumn
private Profile profile;
public Principal() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// omit setters/getters
}
I use RequestFactory to connect with server side.
Here is my RequestFactory:
TarantulaFactory.java
package com.szybieka.tarantula.gwt.client.requestfactory;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
import com.google.web.bindery.requestfactory.shared.Service;
import com.szybieka.tarantula.gwt.client.proxy.PrincipalProxy;
import com.szybieka.tarantula.gwt.client.proxy.ProfileProxy;
import com.szybieka.tarantula.gwt.server.locator.PrincipalServiceLocator;
import com.szybieka.tarantula.gwt.server.locator.ProfileServiceLocator;
import com.szybieka.tarantula.gwt.server.service.PrincipalService;
import com.szybieka.tarantula.gwt.server.service.ProfileService;
public interface TarantulaFactory extends RequestFactory {
PrincipalRequestContext createPrincipalRequest();
ProfileRequestContext createProfileRequest();
#Service(value = ProfileService.class,
locator = ProfileServiceLocator.class)
public interface ProfileRequestContext extends RequestContext {
Request<Void> save(ProfileProxy profile);
Request<ProfileProxy> findProfile(Long id);
}
#Service(value = PrincipalService.class,
locator = PrincipalServiceLocator.class)
public interface PrincipalRequestContext extends RequestContext {
Request<PrincipalProxy> findPrincipal(String login, String password);
Request<PrincipalProxy> findPrincipal(Long id);
Request<PrincipalProxy> findPrincipalByLogin(String login);
Request<Void> save(PrincipalProxy principal);
Request<Void> remove(PrincipalProxy principal);
}
}
Here are proxies for entity classes:
ProfileProxy.java
package com.szybieka.tarantula.gwt.client.proxy;
import java.util.Date;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.ProxyFor;
import com.szybieka.tarantula.core.domain.Profile;
import com.szybieka.tarantula.gwt.server.locator.ProfileLocator;
#ProxyFor(value = Profile.class, locator = ProfileLocator.class)
public interface ProfileProxy extends EntityProxy {
Long getId();
void setId(Long id);
// omit other getter/setter methods
}
PrincipalProxy.java
package com.szybieka.tarantula.gwt.client.proxy;
import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.ProxyFor;
import com.szybieka.tarantula.core.domain.Principal;
import com.szybieka.tarantula.gwt.server.locator.PrincipalLocator;
#ProxyFor(value = Principal.class, locator = PrincipalLocator.class)
public interface PrincipalProxy extends EntityProxy {
Long getId();
String getLogin();
// omit other getter/setter methods
}
A RequestContext is a builder for a batch request that you eventually fire to send to the server for processing. All proxies have to be created and edited from the same RequestContext in a batch request.
Remove your use of ProfileRequestContext and replace profileCtx.create(ProfileProxy.class) with principalCtx.create(ProfileProxy.class).

Resources