I'm learning EJB now.
When I deploy my project to glassfish server. One of my entity beans wasn't deployed. But the other 2 work properly. Here's the entity bean's code:
package com.supinfo.javapetstore.model;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "Items")
public class Item implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String reference;
public Item() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
#Override
public String toString() {
return "Id: " + id + " / reference: " + reference;
}
}
No error or warning appers when deploying.
Thanks a lot.
Try enabling logging,
Assuming your using EclipseLink in Glassfish, add the property to your persistence.xml
<property name="eclipselink.logging.level" value="FINEST"/>
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging
In general tables are not created by default, to enable table creation use the property,
<property name="eclipselink.ddl-generation" value="create-tables"/>
Related
i wanna create objects with intellij (jpa) system,
but after i create objects,
there's no change in h2 console.
i expect that the objects are made like this, enter image description here
(wanna make ITEM and MOVIE objects)
but what i got is this. enter image description here
these are the codes that i wrote.
package hellojpa;
import javax.persistence.Entity;
#Entity
public class Album extends Item{
private String artist;
}
package hellojpa;
import javax.persistence.Entity;
#Entity
public class Book extends Item{
private String author;
private String isbn;
}
package hellojpa;
import org.hibernate.engine.internal.JoinSequence;
import org.hibernate.mapping.Join;
import javax.persistence.*;
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class Item {
#Id
#GeneratedValue
private Long id;
private String name;
private int price;
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 int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
package hellojpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class JpaMain {
public static void main(String[] args){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Movie movie = new Movie();
movie.setDirector("aaaa");
movie.setActor("bbbb");
movie.setName("바람과 함께 사라지다");
movie.setPrice(10000);
tx.commit();
}catch(Exception e){
tx.rollback();
} finally{
em.close();
}
emf.close();
}
}
package hellojpa;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
#Entity
public class Locker {
#Id
#GeneratedValue
private Long id;
private String name;
#OneToOne(mappedBy = "locker")
private Member member;
}
package hellojpa;
import net.bytebuddy.dynamic.TypeResolutionStrategy;
import org.hibernate.annotations.Fetch;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity
public class Member {
#Id #GeneratedValue
#Column(name = "MEMBER_ID")
private Long id;
#Column(name = "USERNAME")
private String username;
#ManyToOne
#JoinColumn(name = "Team_ID",insertable = false, updatable = false)
private Team team;
#OneToOne
#JoinColumn(name ="LOCKER_ID")
private Locker locker;
#OneToMany(mappedBy = "member")
private List<MemberProduct> memberProducts = new ArrayList<>();
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
public String getUsername() {return username;}
public void setUsername(String username) {this.username = username;}
}
package hellojpa;
import javax.persistence.*;
import java.time.LocalDateTime;
#Entity
public class MemberProduct {
#Id
#GeneratedValue
private Long id;
#ManyToOne
#JoinColumn(name="MEMBER_ID")
private Member member;
#ManyToOne
#JoinColumn(name = "PRODUCT_ID")
private Product product;
private int count;
private int price;
private LocalDateTime orderDateTime;
}
package hellojpa;
import javax.persistence.Entity;
#Entity
public class Movie extends Item{
private String director;
private String actor;
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
}
package hellojpa;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity
public class Product {
#Id
#GeneratedValue
private Long id;
private String name;
#OneToMany (mappedBy = "product")
private List<MemberProduct> memberProducts = new ArrayList<>();
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;
}
}
package hellojpa;
public enum RoleType {
GUEST, USER, ADMIN
}
package hellojpa;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity
public class Team {
#Id #GeneratedValue
#Column(name = "TEAM_ID")
private Long id;
private String name;
#OneToMany
#JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
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 List<Member> getMembers() {
return members;
}
public void setMembers(List<Member> members) {
this.members = members;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
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_2.xsd">
<persistence-unit name="hello">
<properties>
<!-- 필수 속성 -->
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- 옵션 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="10"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
You forgot to use the entityManager to persist your new entity. Therefore, jpa does not know about the new entity and nothing is saved.
Just add : em.persist(movie);
The screenshots you provided, in combination with <property name="hibernate.hbm2ddl.auto" value="create" />, suggests that you were not finished creating entity classes when you first run your application. Now if you use hibernate.hbm2ddl.auto = create and there is allready a schema present in your H2, it won't update the schema even though you added one or more entity classes.
The community documentation suggests that you use hibernate.hbm2ddl.auto = update in order to update the schema when the application is run.
Please note that, according to this post, it is not safe to use update in a productive environment.
Despite the best efforts of the Hibernate team, you simply cannot rely on automatic updates in production. Write your own patches, review them with DBA, test them, then apply them manually.
Theoretically, if hbm2ddl update worked in development, it should work in production too. But in reality, it's not always the case.
I hope this helps.
I'm working with many-to-one relationship between my two tables(Employee and Department) in which any Employee can work in more than one department. I used the #ManyToOne annotation on the Department object field which I created in Employee entity class. Now when I persist the Employee entity with a particular department, it works fine but when I try to persist another Employee entity with the same department, it creates a new Department entity with the same name and persists it with different id. What I expect it to do is that when I persist an Employee entity with already persisted department, it should just update the foriegn key of the Employee entity to point the id of that department. Sorry if I didnt got the many-to-one concept totally.
EMPLOYEE entity
package com.test.domain;
import javax.persistence.CascadeType;
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.TableGenerator;
#Entity
public class Employee {
#TableGenerator(name="Empl_Gen", table="ID_GEN",pkColumnName="GEN_NAME",valueColumnName="GEN_VALUE", initialValue=0, allocationSize=1)
#Id#GeneratedValue(generator="Empl_Gen",strategy=GenerationType.TABLE)
private Long id;
private String Name;
private String Country;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="DEPT_ID")
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getCountry() {
return Country;
}
public void setCountry(String country) {
Country = country;
}
}
DEPARTMENT entity
package com.test.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.TableGenerator;
#Entity
public class Department {
#TableGenerator(name="DEP_GEN",table="ID_GEN",pkColumnName="GEN_NAME",valueColumnName="GEN_VALUE", pkColumnValue="DEP_GEN",initialValue=0,allocationSize=1)
#Id#GeneratedValue(strategy=GenerationType.TABLE,generator="DEP_GEN")
private Long id;
private String name;
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;
}
}
package com.test.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.test.domain.Employee;
import com.test.service.EmployeeService;
/**
* Handles requests for the application home page.
*/
#Controller
#RequestMapping("/addEmployee")
public class HomeController {
#Autowired
EmployeeService service;
#RequestMapping(method=RequestMethod.GET)
public String getform(Model model)
{
model.addAttribute("employee",new Employee());
return "home";
}
#RequestMapping(method=RequestMethod.POST)
public String setform(Employee employee)
{
service.save(employee);
return"success";
}
}
package com.test.dao;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.test.domain.Employee;
#Repository
#Transactional
public class Employeedaoimpl implements Employeedao
{
#PersistenceContext
EntityManager manager;
#Override
public void save(Employee employee) {
manager.persist(employee);
}
}
Try this:
#TableGenerator(name="DEP_GEN",table="ID_GEN",pkColumnName="GEN_NAME",valueColumnName="GEN_VALUE", pkColumnValue="DEP_GEN",initialValue=0,allocationSize=1)
#Id#GeneratedValue(strategy=GenerationType.TABLE,generator="DEP_GEN")
#Column(name = "DEPT_ID")
private Long id;
I don't know how I can persist an entity(with enum) to the database.
When I fill my form like this;
form.setTypZamowienia(SlownikZamowienie.SENIOR)
then 666 is stored in the database. But when I try like this;
form.setTypZamowienia(SlownikZamowienie.valueOf(request.getParameter("typKlienta").trim()));
0 is stored in the database.
How do I make this work?
For any help I will be very grateful.
My enum :
public enum SlownikZamowienie
{
JUNIOR(42),
SENIOR(666),
PRINCIPAL(31416);
private final int wartosc;
SlownikZamowienie(int wartosc) {
this.wartosc = wartosc;
}
}
My Entity:
package test.jpa.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import test.enums.SlownikZamowienie;
#Entity
#Table(name="Piess")
public class Pies implements Serializable {
private static final Long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
int id;
#Column(name = "imie")
String imie;
#Enumerated
#Column(name = "rasa")
SlownikZamowienie typzamowienia;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getImie() {
return imie;
}
public void setImie(String imie) {
this.imie = imie;
}
public SlownikZamowienie getTypzamowienia() {
return typzamowienia;
}
public void setTypzamowienia(SlownikZamowienie typzamowienia) {
this.typzamowienia = typzamowienia;
}
}
As of JPA 2.1 you can use an attribute converter (known as a UserType in the Hibernate world). See these two articles for details on how to implement such a solution:
www.thoughts-on-java.org/jpa-21-type-converter-better-way-to/
www.thoughts-on-java.org/jpa-21-how-to-implement-type-converter/
I'am working with JPA eclipselink at the moment and like to connect to my Database with Eclipselink
I have some classes for de Tables in My database and a Query to get my Entries:
final Query query = entityManager.createQuery("SELECT q FROM FDC_DBCHANGE q ORDER BY q.CHANGE_ID");
I made some classes for my tables:
FDC_DBCHANGE
package com.bechtle.dbchanges.model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class FDC_DBCHANGE {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private long CHANGE_ID;
private String CHANGE_NAME;
private String CHANGE_DATE;
private int CHANGE_NUMBER;
#OneToMany(mappedBy = "FDC_DBCHANGE")
private final List<FDC_EXECUTED> checkBoxes = new ArrayList<FDC_EXECUTED>();
public String getChangeName() {
return CHANGE_NAME;
}
public void setChangeName(final String pChangeName) {
CHANGE_NAME = pChangeName;
}
public String getChangeDate() {
return CHANGE_DATE;
}
public void setChangeDate(final String pChangeDate) {
CHANGE_DATE = pChangeDate;
}
public int getChangeNumber() {
return CHANGE_NUMBER;
}
public void setChangeNumber(final int pChangeNumber) {
CHANGE_NUMBER = pChangeNumber;
}
public List<FDC_EXECUTED> getCheckBoxes() {
return checkBoxes;
}
#Override
public String toString() {
return "FDC_DBCHANGE [CHANGE_NAME=" + CHANGE_NAME + ", CHANGE_DATE="
+ CHANGE_DATE + "CHANGE_NUMBER=" + CHANGE_NUMBER + "]";
}
}
FDC_EXECUTED
package com.bechtle.dbchanges.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
#Entity
public class FDC_EXECUTED {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private int ENTRY_ID;
private FDC_DBCHANGE FDC_DBCHANGE;
private FDC_SYSTEM FDC_SYSTEM;
#OneToOne
#JoinColumn
public FDC_DBCHANGE getDbChange() {
return FDC_DBCHANGE;
}
public void setDbChange(final FDC_DBCHANGE pDbChange) {
FDC_DBCHANGE = pDbChange;
}
#OneToOne
#JoinColumn
public FDC_SYSTEM getSystem() {
return FDC_SYSTEM;
}
public void setSystem(final FDC_SYSTEM pSystem) {
FDC_SYSTEM = pSystem;
}
}
and FDC_SYSTEM
package com.bechtle.dbchanges.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class FDC_SYSTEM {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private int SYSTEM_ID;
private String NAME;
private FDC_EXECUTED fdcexecuted;
public String getName() {
return NAME;
}
public void setName(final String pName) {
NAME = pName;
}
#OneToMany(mappedBy = "FED_SYSTEM")
public FDC_EXECUTED getExecuted() {
return fdcexecuted;
}
public void setExecuted(final FDC_EXECUTED pExecuted) {
fdcexecuted = pExecuted;
}
}
When I run it on my Tomcat there is this Exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "FDC_DBCHANGE_CHANGE_ID": invalid identifier
Error Code: 904
Call: SELECT ENTRY_ID, FDC_DBCHANGE_CHANGE_ID, FDC_SYSTEM_SYSTEM_ID FROM FDC_EXECUTED WHERE (FDC_DBCHANGE_CHANGE_ID = ?)
bind => [1 parameter bound]
Query: ReadAllQuery(name="checkBoxes" referenceClass=FDC_EXECUTED sql="SELECT ENTRY_ID, FDC_DBCHANGE_CHANGE_ID, FDC_SYSTEM_SYSTEM_ID FROM FDC_EXECUTED WHERE (FDC_DBCHANGE_CHANGE_ID = ?)")
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:932)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:816)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
Eclipselink tries to run the SQL Statement SELECT ENTRY_ID, FDC_DBCHANGE_CHANGE_ID, FDC_SYSTEM_SYSTEM_ID FROM FDC_EXECUTED WHERE (FDC_DBCHANGE_CHANGE_ID = ?)
instead of SELECT ENTRY_ID, CHANGE_ID, SYSTEM_ID FROM FDC_EXECUTED WHERE (CHANGE_ID = ?)
I don't konw why...
I hope someone can help me and sorry for my bad english...
obsidianfarmer
Ok, problem solved, its cause Eclipselink needs an OID I have no acces to, that was the problem...
Suppose I have the following simple Customer/Order implementation:
A record of customers defined by a Customer class.
Each customer can have multiple orders defined by an Order class.
Drawing on the explanation of Transparent Indirection from here and Container Policies from here my understanding of these concepts EclipseLink is as follows:
Transparent Indirection allows me to say
Customer customer = Customer.getCustomerById(1);
Set<Order> orders = customer.getOrders();
Two points to note are:
Indirection allows lazy loading of attributes so a customer's orders are only fetched from the DB on line 2, not line 1.
I can treat the orders of a customer as a Set (or Collection or List or Map) of objects of type Order.
The Container Policy tells to EclipseLink which actual class should be used for the Set and it should therefore implement Set in the example above.
That is my understanding of Transparent Indirection and Container Policies in EclipseLink.
I am seeing the following error when I try to access the database:
Exception [EclipseLink-148] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The container policy [CollectionContainerPolicy(class org.eclipse.persistence.indirection.IndirectSet)] is not compatible with transparent indirection.
Mapping: org.eclipse.persistence.mappings.OneToManyMapping[orders]
Descriptor: RelationalDescriptor(my.model.Customer --> [DatabaseTable(Customer)])
I'm sure I have an error in my code somewhere which I am trying to debug but I didn't specify the CollectionContainerPolicy mentioned in the error so I assume org.eclipse.persistence.indirection.IndirectSet is the default. But if I'm using the default policy then I'm not sure what the cause of this error may be or which policy I should be using.
For now, I'd just like to know if my understanding of Transparent Indirection and Container Policies as I mentioned above is correct.
If it is correct I'm probably missing something relatively small in my code (an invocation or configuration option etc.) but if I'm not understanding the concepts then clearly I need to do more research first.
Customer model
package my.model;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* The persistent class for the customer database table.
*
*/
#Entity
#Table(name=Customer.TBL_NAME)
#NamedQueries({
#NamedQuery(name=Customer.QRY_BY_NAME,query="Select object(a) from Customer a where " +
"a.name=:" + Customer.PRM_NAME),
#NamedQuery(name=Customer.QRY_ALL, query="select object(a) from Customer a")
})
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
// Table specific onstants
public static final String TBL_NAME = "Customer";
public static final String QRY_BY_NAME = TBL_NAME + ".byName";
public static final String QRY_ALL = TBL_NAME + ".all";
public static final String PRM_NAME = "name";
private int id;
private String name;
private Set<Order> orders;
public Customer() {
}
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//bi-directional many-to-one association to Order
#OneToMany(mappedBy="customer")
public Set<Order> getOrders() {
return this.orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
Order model
package my.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* The persistent class for the order database table.
*
*/
#Entity
#Table(name=Order.TBL_NAME)
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
// Table constants
public static final String TBL_NAME = "Order";
private int id;
private Customer customer;
public Order() {
}
#Id
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
//bi-directional many-to-one association to Customer
#ManyToOne
public Customer getCustomer() {
return this.customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
Your understanding is correct, but shouldn't be needed as this isn't something you need to configure when using JPA. EclipseLink will determine the collection policy and implementation to use based on the type of the property and the lazy/eager setting, and it seems to be doing so correctly. The exception is thrown in error, probably due to classloader issues so that the classloader used for init isn't the one used to validate against, but I don't know how that could happen. You will need to look at the environment this is running in as the exception itself is just a symptom