Populating Id column with a predefined Prefix in Hibernate - java

I am working on java Web Project and have to insert user records in Table.
There is a requirement to add prefix to the ID column value in user table which means We have to add prefix like 'user' to value generated by sequence to get final value for id column as 'user00001' which is primary key for each new record which got inserted in Table.
I have created a sequence and DB trigger to populate the ID column when any record is inserted in DB to get above requirement satisfied. I am using Oracle 11g DB.
In my Web application,i have to use Hibernate to do DB related tasks like insert,update
I have following xml configuration for my Table
<hibernate-mapping>
<class name="UserProfile" table="USER_PROFILE">
<id name="id" type="string">
<column name="id"/>
<generator class="sequence">
<param name="sequence">USER_PROFILE_SEQ</param>
</generator>
</id>
<property name="firstName" type="string" column="FIRST_NAME"/>
<property name="middleName" type="string" column="MIDDLE_NAME"/>
<property name="lastName" type="string" column="LAST_NAME"/>
</class>
</hibernate-mapping>
And have created Java bean for User profile as follows
public class UserProfile {
private String id;
private String firstName;
private String middleName;
private String lastName;
public UserProfile() {
super();
}
/**
* #return the id
*/
public String getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* #return the firstName
*/
public String getFirstName() {
return firstName;
}
/**
* #param firstName the firstName to set
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* #return the middleName
*/
public String getMiddleName() {
return middleName;
}
/**
* #param middleName the middleName to set
*/
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
/**
* #return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* #param lastName the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Hibernate is using the sequence which i have assigned in xml mapping and getting the value but instead of populating id column value as sequence number i want it to take value generated by DB trigger which takes sequence value and add a prefix like 'user' to it before inserting the record in table.
So my question is how to populate Id column in hibernate with trigger generated value? As i am new to Hibernate, i downloaded latest hibernate version 4.2.7 distribution.Any help will be greatly appreciated.
Note : I cannot drop Triggers as its requirement from Application team.

Does this post help you? https://forum.hibernate.org/viewtopic.php?t=973262
In that post is presented custom generator class that lets database to assign id.
Mapping will be like this:
<id name="id" type="string">
<column name="id"/>
<generator class="jpl.hibernate.util.TriggerAssignedIdentityGenerator" />
</id>

Related

ERROR: ORA-02289: sequence does not exist in hibernate [duplicate]

This question already has answers here:
Hibernate-sequence doesn't exist
(17 answers)
Closed 5 years ago.
I am developing a very basic hibernate application and am stuck with the error:
ERROR: ORA-02289: sequence does not exist.
Attached are the related files. I see this question already been asked in stack overflow but none of them could solve the issue. I have created the sequence school_seq already in Oracle DB.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="hibEx">
<class name="School" table="school">
<id name="id" column="ID" type="int">
<generator class="sequence">
<param name="sequence">SCHOOL_SEQ</param>
</generator>
</id>
<property name="name" column="NAME"></property>
<property name="subject" column="SUBJECT"></property>
<property name="marks" column="MARKS"></property>
</class>
</hibernate-mapping>
POJO CLASS
package hibEx;
public class School {
private String name;
private String subject;
private int marks;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public int getMarks() {
return marks;
}
public void setMarks(int marks) {
this.marks = marks;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
First i have created sequence like the below:
CREATE SEQUENCE school_seq
START WITH 411
INCREMENT BY 1;
As i am facing this issue,i have tried multiple practices based on the comments in the group
and later altered the table like the below:
alter sequence school_seq
MINVALUE 411
MAXVALUE 1000
NOCYCLE
CACHE 20
NOORDER
thanks for your support in clearing this problem..On further research i found a comment from Li Ying in the link click here .
It says In Hibernate 5, the param name for the sequence has been changed to <param name="sequence_name">xxxxxx_seq</param> from <param name="sequence">xxxxxx_seq</param>
Make sure your sequence was created in the same schema as the table. Connect with the owner of the SCHOOL table and query these data dictionary views to make sure that the same user owns the table and the sequence.
SELECT
s.sequence_name,
s.sequence_owner
FROM
all_sequences s
WHERE
s.sequence_name = 'SCHOOL_SEQ';
and
SELECT
t.table_name,
t.owner
FROM
all_tables t
WHERE
t.table_name = 'SCHOOL';

How to add column automatically in hibernate.hbm.xml and users.java

i have java project i am creating with hibernate using NetBeans ide7.4 till now i have created
users.hbm.xml file and users.java file which based on table in database but now i have added some more column in users table so please tell me how can i update my users.hbm.xml and users.java corresponding my database table when i increase table in database or add some more column in table for doing it i have fallow number of tutorial but still now i am facing problem so please solve my problem
before my users table has only 1 column
id
and my users.java is
package clinic.entity;
// Generated 17 Jan, 2014 4:36:15 PM by Hibernate Tools 3.6.0
public class Users implements java.io.Serializable {
private int id;
public Users() {
}
public Users(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
}
and my users.hbm.xml file is
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated 17 Jan, 2014 4:36:16 PM by Hibernate Tools 3.6.0 -->
<hibernate-mapping>
<class name="clinic.entity.Users" table="users" catalog="clinic_mgmt">
<id name="id" type="int">
<column name="id" />
<generator class="assigned" />
</id>
</class>
</hibernate-mapping>
now i have added 2 more column in table then schema is this
id|name |email
so tell me how to update my both file automatically
It's easier to do things in the opposite direction: update Java first, then generate the database schema with (because the xml file can contain most of the schema).
Now that you've added these columns, you must add field in your java file for each new column, then map them in the xml file.
For instance, if you have a new column email VARCHAR(128), you would add a String field in then java class, then map in with a <property> element in your xml file:
users.java:
private String email;
...
public String getEmail() {
return email;
}
public void setEmail(String newValue) {
email = newValue;
}
users.hbm.xml:
<property column="EMAIL" length="128" name="email"/>
you can use javax.persistence package annotation for that :
#Basic(fetch=FetchType.LAZY)
#Column(name="firstname")
private String firstname;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}

Hibernate mapping of two classes to a single row in a table

Is it possible to map two classes into single row in a table in Hibernate
I have two classes:
public class Student implements java.io.Serializable {
private int studentId;
private String studentName;
public Student() {
}
public int getStudentId() {
return this.studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return this.studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
}
and :
public class Address implements java.io.Serializable {
private String street;
private String city;
public Address() {
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
I would like to create a table :
CREATE TABLE "STUDENT"
("STUDENTID" NUMBER(10,0) PRIMARY KEY,
"STUDENTNAME" VARCHAR2(250),
"STREET" VARCHAR2(250),
"CITY" VARCHAR2(250)
)
and map STUDENTID and STUDENTNAME from STUDENT class and STREET and CITY from the ADDRESS class.
Mappings I have done currently is the following:
<hibernate-mapping>
<class name="com.vaannila.student.Address" table="STUDENT">
<id>
<generator class="assigned"/>
</id>
<property name="street" column="SREET" type="string" length="250"/>
<property name="city" column="CITY" type="string" length="250"/>
</class>
</hibernate-mapping>
and :
<hibernate-mapping>
<class name="com.vaannila.student.Student" table="STUDENT">
<id name="studentId" column="STUDENTID" type="int"/>
<property name="studentName" column="STUDENTNAME" type="string" length="250"/>
</class>
</hibernate-mapping>
I am getting error:
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from resource com/vaannila/student/Address.hbm.xml
Caused by: org.hibernate.MappingException: must specify an identifier type: com.vaannila.student.Address
Please help
This is bad design, from both a Java object and database entity point of view. Look at your address configuration file - I think you can see where it falls apart, evidenced by your attempt to define an id field. Always try and keep in mind what you are trying to model, in this case, Students and Addresses. If those two entities are always going to be one-to-one then go ahead and consolidate the Address and Student classes (as opposed to trying to split them up).
Of course, I think you will find that the relationship is really Many-to-One. And if we are talking college here than its Very-Many-to-One. The examples on Vaanila are structured that way for a reason, I recommend studying them in detail:
http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-many-to-one-1.html
You should be able to do this pretty easily. Here is how using annotations from another question:
Single Table Inheritance WITHOUT Discriminator column
You will have to figure out the translation to XML on your own if that is desired!
yes its possible you can use component tag in xml.

JPA - using annotations in a model

My application runs on JPA/Hibernate, Spring and Wicket. I'm trying to convert our ORM from XML files to JPA annotations. The annotated model looks like this:
#Entity
#Table(name = "APP_USER")
public class User extends BaseObject {
private Long id;
private String firstName;
private String lastName;
private String email;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
#Column(name = "ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name="FIRST_NAME")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name="LAST_NAME")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name="EMAIL")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
/**
* #return Returns firstName and lastName
*/
public String getFullName() {
return firstName + ' ' + lastName;
}
}
Originally, though, it was without annotation and the mapping was described in User.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.appfuse.model.User" table="app_user">
<id name="id" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<property name="firstName" column="first_name" not-null="true"/>
<property name="lastName" column="last_name" not-null="true"/>
<property name="email" column="email"/>
</class>
</hibernate-mapping>
When I delete the mapping file and try to use just the annotations, the entityManagerFactory doesn't get created, with the exception
org.hibernate.PropertyNotFoundException:
Could not find a setter for property
fullName in class
org.appfuse.model.User.
There's no mapping set for this property, because it's just a convenience method. What do I do wrong?
Mark the method as #Transient so Hibernate will ignore it:
/**
* #return Returns firstName and lastName
*/
#Transient
public String getFullName() {
return firstName + ' ' + lastName;
}
By default, everything that looks like a getter is mapped.

Help with Hibernate Collection Foreign Key Mapping

I'm running into significant difficulty getting my mapping file to work with a collection of elements via a foreign key in Hibernate. Java will try to load these files below and won't have any runtime exceptions, but the events table is never loaded as an object of an employee (it will remain null, but every other attribute loads from the DB). In my MySQL database, I have the following:
TABLE: Employees
Primary Key: username varchar
name varchar
areacode INTEGER
phone INTEGER
addressNumber INTEGER
addressLocation varchar
email varchar
TABLE: Events
Primary Key: ID INTEGER
startDate DateTime
endDate DateTime
customerName varchar
employeeUsername varchar
<?xml version="1.0"?>
<class name="Employee" table="Employees">
<id name="username" column="username" type="string"/>
<many-to-one name="contact" class="Contact" column="username" unique="false" update="false" insert="false" optimistic-lock="true" not-found="exception" embed-xml="true" />
</class>
<class name="Contact" table="Employees">
<id name="username" column="username" type="string"/>
<property name="name" column="name" type="string"/>
<property name="addressNumber" column="addressNumber" type="int"/>
<property name="areacode" column="areacode" type="int"/>
<property name="phone" column="phone" type="int"/>
<property name="addressLocation" column="addressLocation" type="string"/>
<property name="email" column="email" type="string"/>
</class>
<?xml version="1.0"?>
<class name="Event" table="Events">
<id name="ID" column="ID" type="int">
<generator class="assigned"/>
</id>
<property name="startDate" column="startDate" type="date"/>
<property name="endDate" column="endDate" type="date"/>
<property name="customerName" column="customerName" type="string"/>
</class>
<class name="Employee" table="Events" entity-name="Employee2">
<id name="username" column="employeeUsername" type="string"/>
<list name="events" cascade="all">
<key column="employeeUsername"/>
<list-index column="ID"/>
<one-to-many class="Event"/>
</list>
</class>
Assume the hibernate.cfg.xml file exists and works (If you feel this needs to be shown, please let me know). It does include both of the files in its mapping files part.
I have a feeling my error is probably in my declaration of the collection of events in my "list" declaration. Here are the Java classes:
package org.hibernate.employee;
import java.util.Date;
public class Event {
private int ID;
private Date startDate;
private Date endDate;
private String customerName;
public Event(){
System.out.println("blah");
}
/**
* #return the iD
*/
public int getID() {
return ID;
}
/**
* #param id the iD to set
*/
public void setID(int id) {
ID = id;
}
/**
* #return the startDate
*/
public Date getStartDate() {
return startDate;
}
/**
* #param startDate the startDate to set
*/
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
/**
* #return the endDate
*/
public Date getEndDate() {
return endDate;
}
/**
* #param endDate the endDate to set
*/
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
/**
* #return the customerName
*/
public String getCustomerName() {
return customerName;
}
/**
* #param customerName the customerName to set
*/
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
}
/*
* File: Contact.java
*/
package org.hibernate.employee;
/**
* This class represents a Contact information for an Employee.
*
*/
public class Contact {
private int username; // the contact identifier in the database
private int areacode; // the contact areacode
private int phone; // the contact phone
private String name; // the contact's name
private int addressNumber; // the contact's address number
private String addressLocation; // the contact's address location
private String email; // the contact's email
/**
* Constructs a Contact object.
*/
public Contact() {
}
/**
* #return the areacode
*/
public int getAreacode() {
return areacode;
}
/**
* #param areacode the areacode to set
*/
public void setAreacode(int areacode) {
this.areacode = areacode;
}
/**
* #return the phone
*/
public int getPhone() {
return phone;
}
/**
* #param phone the phone to set
*/
public void setPhone(int phone) {
this.phone = phone;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the addressNumber
*/
public int getAddressNumber() {
return addressNumber;
}
/**
* #param addressNumber the addressNumber to set
*/
public void setAddressNumber(int addressNumber) {
this.addressNumber = addressNumber;
}
/**
* #return the addressLocation
*/
public String getAddressLocation() {
return addressLocation;
}
/**
* #param addressLocation the addressLocation to set
*/
public void setAddressLocation(String addressLocation) {
this.addressLocation = addressLocation;
}
/**
* #return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
public String toString(){
String retVal = "";
retVal += "Address: " + this.addressNumber + " " + this.addressLocation + "\n";
retVal += "Email: " + this.email + "\n";
retVal += "Phone: " + this.areacode + " " + this.phone + "\n";
retVal += "Name: " + this.name + "\n";
return retVal;
}
public void setUsername(int username) {
this.username = username;
}
public int getUsername() {
return username;
}
}
/*
* File: Employee.java
*/
package org.hibernate.employee;
import java.util.List;
/**
* This class represents an Employee in a company database.
*
*/
public class Employee {
private String username; // the employee's username
private Contact contact; // the employee's contact information
private List events;
/**
* Constructs an Employee object.
*/
public Employee() {
super();
}
/**
* #return the username
*/
public String getUsername() {
return username;
}
/**
* #param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* #return the contact
*/
public Contact getContact() {
return contact;
}
/**
* #param contact the contact to set
*/
public void setContact(Contact contact) {
this.contact = contact;
}
/**
* #return the events
*/
public List getEvents() {
return events;
}
/**
* #param events the events to set
*/
public void setEvents(List events) {
this.events = events;
}
public String toString(){
String retVal = "";
System.out.println(events);
retVal += "Username: " + username + "\n";
retVal += "Contact: " + contact + "\n";
return retVal;
}
}
Your mappings are wrong for two (main) reasons:
Mapping both Employee and Contact to the same table that way is not going to work. many-to-one requires a foreign key (e.g. a separate column); you're trying to reuse the primary key instead.
Re-mapping Employee class to a different table isn't going to work either - table and class are incompatible. Using a different entity name prevents an immediate error, but that's not the appropriate usage of it.
What you should do instead is:
Map Contact as component.
Map collection of events directly on Employee as one-to-many association.
Something like:
<class name="Employee" table="Employees">
<id name="username" column="username" type="string"/>
<component name="Contact" class="Contact"> <!-- class attribute optional -->
<property name="name" column="name" type="string"/>
<property name="addressNumber" column="addressNumber" type="int"/>
<property name="areacode" column="areacode" type="int"/>
<property name="phone" column="phone" type="int"/>
<property name="addressLocation" column="addressLocation" type="string"/>
<property name="email" column="email" type="string"/>
</component>
<list name="events" cascade="all">
<key column="employeeUsername"/>
<list-index column="event_idx"/>
<one-to-many class="Event"/>
</list>
</class>
Note that list-index should really be a separate column in your table if you want to map list of events as ordered list; you can't map it to id. If you don't want to define it as a column, you can either map the list as <bag> instead (and, optionally, specify order-by attribute to sort that bag by) or map it as collection of composite elements where each Event will no longer be an independent entity. Whether or not that's applicable depends on your business requirements.

Categories

Resources