Hibernate saveOrUpdate does not update - java

I am trying to update a table row using the session.saveOrUpdate() method in Hibernate.
However, it is unable to update the row and tries to save it by producing an insert statement. This insert does not work due to a few non-nullable fields in my DB.
I am able to retrieve the Id of the object to be saved at the DAO layer, so I am not able to understand why it doesn't just update the corresponding row in the DB table.
Bean Class: (BaseEntityBean has the Id, CreatedBy, etc.)
public class EmployeeMasterBean extends BaseEntityBean {
/**
*
*/
private static final long serialVersionUID = 1L;
#Column(name = "FirstName", nullable = false)
private String firstName;
#Column(name = "LastName", nullable = false)
private String lastName;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "Dob", insertable = true, updatable = true, nullable = false)
private Date dateOfBirth;
#Column(name = "Email", length = 100)
private String email;
#Column(name = "PhoneNumber", nullable = false)
private String phoneNumber;
#Column(name = "Address1", nullable = false)
private String address1;
#Column(name = "Type", nullable = false)
private Short employeeType;
#Column(name = "Gender", nullable = false)
private Short gender;
/**
* #return the firstName
*/
public final String getFirstName() {
return firstName;
}
/**
* #param firstName the firstName to set
*/
public final void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* #return the lastName
*/
public final String getLastName() {
return lastName;
}
/**
* #param lastName the lastName to set
*/
public final void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* #return the dateOfBirth
*/
public final Date getDateOfBirth() {
return dateOfBirth;
}
/**
* #param dateOfBirth the dateOfBirth to set
*/
public final void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
/**
* #return the email
*/
public final String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public final void setEmail(String email) {
this.email = email;
}
/**
* #return the phoneNumber
*/
public final String getPhoneNumber() {
return phoneNumber;
}
/**
* #param phoneNumber the phoneNumber to set
*/
public final void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
* #return the address1
*/
public final String getAddress1() {
return address1;
}
/**
* #param address1 the address1 to set
*/
public final void setAddress1(String address1) {
this.address1 = address1;
}
/**
* #return the employeeType
*/
public final Short getEmployeeType() {
return employeeType;
}
/**
* #param employeeType the employeeType to set
*/
public final void setEmployeeType(Short employeeType) {
this.employeeType = employeeType;
}
/**
* #return the gender
*/
public final Short getGender() {
return gender;
}
/**
* #param gender the gender to set
*/
public final void setGender(Short gender) {
this.gender = gender;
}
}
DAO Method:
public EmployeeMasterBean saveOrUpdateEmployee(EmployeeMasterBean employeeMasterBean) throws Exception{
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSessionFactory().openSession();
tx = session.beginTransaction();
session.saveOrUpdate(employeeMasterBean);
tx.commit();
} finally {
session.close();
}
return employeeMasterBean;
}
Eclipse debugger exceptions thrown are:
could not insert: [com.indven.gpil.hrd.entity.EmployeeMasterBean]
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'CreatedBy' cannot be null

As the error message say, the database has a column createdby which can't be null.
When you called saveOrUpdate() someone has set this property to null so the update isn't possible.

I think CreatedBy column is present in DB table as notnull but your bean does not have this column mapped, hence a null value is sent when you do a saveOrUpdate, which causes Above exception to be thrown.
Either add a mapping to CreatedBy in your bean with some default value and let trigger etc can update the default value. Or if you can change the column to be nullable in Database

The bean did not have the rowVersion property (for optimistic locking) set, and hence by default it was null. Hibernate thus interpreted this as a new record, and kept saving it.
I fixed it by storing the row version in my Value Object and the corresponding Bean whenever I attempted to save or update any records.

we can add the following to jsp form to match with entity PK (id),
<form:hidden path="id" />

Related

Room one-to-many warning

When creating my contact DAO and related classes, I am getting the following error:
The query returns some columns [mContactId, mAddress, mPostcode, mCity, mCountry, mAddressType]
which are not used by org.linphone.contacts.managementWS.ContactWithAddresses. You can use
#ColumnInfo annotation on the fields to specify the mapping.
org.linphone.contacts.managementWS.ContactWithAddresses has some fields [mName, mSurname,
mFullName, mCompany, mNote, mIsBlocked] which are not returned by the query. If they are not
supposed to be read from the result, you can mark them with #Ignore annotation. You can suppress
this warning by annotating the method with #SuppressWarnings(RoomWarnings.CURSOR_MISMATCH).
Columns returned by the query: id, mContactId, mAddress, mPostcode, mCity, mCountry,
mAddressType. Fields in org.linphone.contacts.managementWS.ContactWithAddresses: id, mName,
mSurname, mFullName, mCompany, mNote, mIsBlocked.
In my ContactsDao:
#Query("SELECT * FROM contacts_table")
List<Contact> getAll();
#Transaction
#Query("SELECT * FROM phone_numbers_table")
List<ContactWithNumbers> getContactsWithPhoneNumbers();
ContactsWithNumbers.java:
#Embedded public Contact contact;
#Relation(parentColumn = "id", entityColumn = "mContactId", entity = PhoneNumbers.class)
public List<PhoneNumbers> numbers;
And below is my Contact.java:
#Entity(tableName = "contacts_table")
public class Contact {
// TODO - members should be private, not public. Changed to workaround error.
#PrimaryKey(autoGenerate = true)
public int id;
/* String resource ID for the user name */
#SerializedName("first_name")
public String mName;
/* String resource ID for the user surname */
#SerializedName("last_name")
public String mSurname;
/* String resource ID for the user's full name */
#SerializedName("full_name")
public String mFullName;
/* String resource ID for the user company */
#SerializedName("company")
public String mCompany;
/* String resource ID for the user's phone number(s) */
/** String resource ID for the user's note */
#SerializedName("note")
public String mNote;
#SerializedName("blocked")
public boolean mIsBlocked;
/**
* #param firstName
* #param lastName
* #param fullName
* #param company
* #param note
* #param isBlocked
*/
#Ignore
public Contact(
String firstName,
String lastName,
String fullName,
String company,
String note,
boolean isBlocked) {
super();
this.mName = firstName;
this.mSurname = lastName;
this.mFullName = fullName;
this.mCompany = company;
this.mNote = note;
this.mIsBlocked = isBlocked;
}
public Contact(String name, String surname, String company, String note, boolean isBlocked) {
this.mName = name;
this.mSurname = surname;
this.mCompany = company;
this.mNote = note;
this.mIsBlocked = isBlocked;
}
public int getId() {
return id;
}
public String getmName() {
return mName;
}
public String getmSurname() {
return mSurname;
}
public String getmFullName() {
return mName + " " + mSurname;
}
public String getmCompany() {
return mCompany;
}
public String getmNote() {
return mNote;
}
public boolean getmIsBlocked() {
return mIsBlocked;
}
}
It is quite likely that I have not fully grasped the concept of Room one-to-many relations, but what exactly am I doing wrong here and getting that warning?
It's say very clear: You can use #ColumnInfo annotation on the fields to specify the mapping.
Change your code like this:
#NonNull
#PrimaryKey
#ColumnInfo(name = "id")
private String id;
More at codelab: https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#0

Spring MVC using hibernate Sequence doesn't exist

UserBean Class
#Entity
#Table(name="users")
public class UserBean {
#Id
#GeneratedValue(strategy =GenerationType.AUTO)
#Column(name="ID")
private Integer id;
#Column(name = "NAME")
private String name;
#Column(name = "EMAIL")
private String email;
#Column(name = "AGE")
private int age;
/**
* #return the id
*/
public Integer getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return the age
*/
public int getAge() {
return age;
}
/**
* #param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("UserBean [id=").append(id).append(", name=")
.append(name).append(", email=").append(email).append(", age=")
.append(age).append("]");
return builder.toString();
}
}
I am getting ORA:02289 Sequence doesn't exist
Here is hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<mapping class="com.abc.bean.UserBean" />
</session-factory>
</hibernate-configuration>
Dispatcher package scan
<context:component-scan base-package="com.abc.controller" />
<context:component-scan base-package="com.abc.dao.impl" />
<mvc:annotation-driven />
I have tried the same thing in another laptop and it worked, what is causing the problem? Earlier, I tried to generate a sequence but it didn't worked well
Sql command executed:
create table users(id int primary key,name varchar(20),email varchar(20),age int);
hibernate use sequence for oracle db if you use GenerationType.AUTO (default global sequence name hibernate_sequence) . You should create sequence and configure it in entity mapping , like :
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_generator")
#SequenceGenerator(name="user_generator", sequenceName = "user_seq")
#Column(name="ID",allocationSize = 1)
private Integer id;
Which version of Oracle you using? As per my knowledge Auto increment not supported in 11g but supports in 12c..

org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: core.user.User.userRole[core.user.UserRole]

I get this error with these entity classes. I've viewed this question, but I don't have a persistence.xml, so I'm unsure how to fix this. I'm building these entities with Dropwizard if that helps.
The problem seems to be with how I'm mapping a User to a UserRole. Both classes are in the same package.
User.java
#Entity
#Table(name = "USER")
public class User implements TimestampedItem {
//region Fields
protected String email;
protected String password;
protected String displayName;
protected Long ID;
protected Set<UserRole> userRole;
protected Boolean isActive = true;
protected Boolean isEmailConfirmed = false;
protected DateTime added = new DateTime();
protected DateTime modified = new DateTime();
//endregion
//region Constructors
public User() {
this("", "", "");
}
public User(String email, String password, String displayName) {
this(email, password, displayName, true);
}
public User(String email, String password, String displayName, Boolean isActive) {
this(email, password, displayName, new HashSet<>(), isActive, false);
}
public User(String email, String password, String displayName, Set<UserRole> userRole, Boolean isActive, Boolean isEmailConfirmed) {
this(email, password, displayName, userRole, isActive, isEmailConfirmed, new DateTime(), new DateTime());
}
public User(String email, String password, String displayName, Set<UserRole> userRole, Boolean isActive, Boolean isEmailConfirmed, DateTime added, DateTime modified) {
this.email = email;
this.password = password;
this.displayName = displayName;
this.userRole = userRole;
this.isActive = isActive;
this.isEmailConfirmed = isEmailConfirmed;
this.added = added;
this.modified = modified;
}
//endregion
//region Getters and Setters
/**
* Returns this Users email address
*
* #return this Users email address
*/
#Email
#Column(name = "EMAIL", unique = true, nullable = false, length = 255)
public String getEmail() {
return this.email;
}
/**
* Sets this Users email address
*
* #param email The email address to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* Returns this User's password
*
* #return this User's password
*/
#Column(name = "PASSWORD", nullable = false, length = Passwords.DESIRED_KEY_LENGTH)
public String getPassword() {
return this.password;
}
/**
* Sets this User's password
*
* #param password The password to set
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Returns this User's unique User ID
*
* #return this User's unique User ID
*/
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "USER_ID", unique = true, nullable = false)
public Long getID() {
return this.ID;
}
/**
* Sets this User's unique User ID
*
* #param id The unique ID to set to this user
*/
public void setID(Long id) {
this.ID = id;
}
/**
* Whether this User's profile is isActive
*
* #return true if this User's profile is isActive, false otherwise
*/
#Column(name = "IS_ACTIVE", nullable = false)
public Boolean isActive() {
return this.isActive;
}
/**
* Sets whether this User's profile is isActive
*
* #param active true if this User's profile is isActive, false otherwise
*/
public void setActive(Boolean active) {
this.isActive = active;
}
/**
* Whether this User's email address has been confirmed.
* To confirm an email, they must click the activation link that is sent to their email address
*
* #return true if this User's email has been confirmed, false otherwise
*/
#Column(name = "IS_EMAIL_CONFIRMED", nullable = false)
public Boolean isEmailConfirmed() {
return this.isEmailConfirmed;
}
/**
* Sets whether this User's email address has been confirmed.
* To confirm an email, they must click the activation link that is sent to their email address
*
* #param isEmailConfirmed true if this User's email has been confirmed, false otherwise
*/
public void setEmailConfirmed(Boolean isEmailConfirmed) {
this.isEmailConfirmed = isEmailConfirmed;
}
/**
* Returns this User's display name
*
* #return this User's display name
*/
#Column(name = "DISPLAY_NAME", nullable = false)
public String getDisplayName() {
return this.displayName;
}
/**
* Sets this User's display name
*
* #param displayName The display name to associate with this User
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Set<UserRole> getUserRole() {
return this.userRole;
}
public void setUserRole(Set<UserRole> userRole) {
this.userRole = userRole;
}
#Override
#Column(name = "ADDED", nullable = false)
public DateTime getAdded() {
return this.added;
}
#Override
public void setAdded(DateTime added) {
this.added = added;
}
#Override
#Column(name = "MODIFIED", nullable = false)
public DateTime getModified() {
return this.modified;
}
#Override
public void setModified(DateTime modified) {
this.modified = modified;
}
//endregion
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
// These probably aren't needed, since a user is considered unique by ID alone
// if (!displayName.equals(user.displayName)) return false;
// if (!email.equals(user.email)) return false;
// if (!password.equals(user.password)) return false;
return getID().equals(user.getID());
}
#Override
public int hashCode() {
int result = email.hashCode();
result = 31 * result + password.hashCode();
result = 31 * result + displayName.hashCode();
return result;
}
}
UserRole.java
#Entity
#Table(
name = "user_roles"
, uniqueConstraints = #UniqueConstraint( columnNames = { "role", "USER_ID" } )
)
public class UserRole{
private Integer userRoleId;
private User user;
private String role;
public UserRole() {
}
public UserRole(User user, String role) {
this.user = user;
this.role = role;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_role_id", unique = true, nullable = false)
public Integer getUserRoleId() {
return this.userRoleId;
}
public void setUserRoleId(Integer userRoleId) {
this.userRoleId = userRoleId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "USER_ID", nullable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
#Column(name = "role", nullable = false, length = 45)
public String getRole() {
return this.role;
}
public void setRole(String role) {
this.role = role;
}
}
Did you set up your HibernateBundle properly? Dropwizard Hibernate offers two bundles to set up the persistence unit with hibernate, one being the default HibernateBundle which needs all entity classes passed in the constructor - are both classes passed in?
Alternatively you can use ScanningHibernateBundle and pass in the package name of your entities as String so you don't miss anything in the future. This would look like this in your Application:
private final HibernateBundle<MyConfiguration> hibernate =
new ScanningHibernateBundle<MyConfiguration>("com.acme.entity") {
#Override
public DataSourceFactory getDataSourceFactory(MyConfiguration configuration) {
return configuration.getDataSourceFactory();
}
};
are you use spring frame ? If you use this,you can add this code into appliactionContext.xml
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="dbke" />
<property name="PersistenceXmlLocation" value="classpath:META-INF/jpa-persistence.xml" />
</bean>
you need create jpa-persistence.xmlfirstly.For example:
<?xml version="1.0" encoding="UTF-8"?>
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence version="2.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_2_0.xsd">
<persistence-unit name="dbke" transaction-type="RESOURCE_LOCAL">
<class>core.user.Userrole</class>
<class>core.user.User</class>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
</persistence-unit>
</persistence>

JPA- Showing User Role relationships with Many to Many Hashset ENUMs

My DTO is being stored using JPA Hibernate and I'm able to store the other fields but having trouble trying to store this relationship for the user. The userRoleSet HashSet has ENUMs that represent what roles that user has. Some users with have no roles while someone will have 1 to 3 roles. Each role is different. How would I got about representing this in my database and using JPA? At the moment, the #ManyToMany doesn't work, I miss be missing something else? Essentially, I need to be able to query that specific user in the database and have it return the roles that is assigned to that user.
UserType Enums
public enum UserType
{
ALPHA,BRAVO,CHARLIE
}
Default User DTO JPA
#Entity
#Table(name = "users")
public class DefaultUser implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private long user_id;
#Column(name = "user_name")
private String user_name;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "password")
private String password;
#ManyToMany
private Set<UserType> userRoleSet = new HashSet<UserType>();
/**
* #return the userTypes
*/
public Set<UserType> getUserTypes()
{
return userRoleSet;
}
/**
*
* #param userTypes
* the userTypes to set
*/
public void setUserTypes(Set<UserType> userTypes)
{
this.userRoleSet = userTypes;
}
/**
* #return the user_id
*/
public long getUser_id()
{
return user_id;
}
/**
* #return the user_name
*/
public String getUser_name()
{
return user_name;
}
/**
* #return the firstName
*/
public String getFirstName()
{
return firstName;
}
/**
* #return the lastName
*/
public String getLastName()
{
return lastName;
}
/**
* #return the password
*/
public String getPassword()
{
return password;
}
/**
* #param user_id
* the user_id to set
*/
public void setUser_id(long user_id)
{
this.user_id = user_id;
}
/**
* #param user_name
* the user_name to set
*/
public void setUser_name(String user_name)
{
this.user_name = user_name;
}
/**
* #param firstName
* the firstName to set
*/
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
/**
* #param lastName
* the lastName to set
*/
public void setLastName(String lastName)
{
this.lastName = lastName;
}
/**
* #param password
* the password to set
*/
public void setPassword(String password)
{
this.password = password;
}
}
The #ManyToMany annotation is used to map an association between two entities. For collections of simple types, the annotation to use is #ElementCollection.
PS: you always read and post the complete and exact error message you get when something "doesn't work".

I dont want to save the field with null values in MongoDB using Morphia

I have a form with many fields, I want to save this fields in mongodb in a collection. I want if the user doesnt fill a textfield, then this field should not be saved in the collection.
I have an District Entity. This entity contains another two entities (contact and address).
The District class lokks like this:
public class District {
#Id private ObjectId id;
private String Type;
private String Name;
private Contact contact;
private Address address;
/**
* #return the Type
*/
public String getType() {
return Type;
}
....
/**
* #param Type the Type to set
*/
public void setType(String Type) {
this.Type = Type;
}
For contact I have this Java class:
#Embedded
public class Contact {
private String email;
private String fax;
private String firstname;
private String lastname;
private String gender;
private String telephone;
private String title;
/**
* #return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return the fax
*/
public String getFax() {
return fax;
}
/**
* #param fax the fax to set
*/
public void setFax(String fax) {
this.fax = fax;
}
...
and my form lokks like this:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
Mongo mongo = null;
try {
mongo = new Mongo();
} catch (UnknownHostException ex) {
Logger.getLogger(TestForm.class.getName()).log(Level.SEVERE, null, ex);
}
Morphia morphia=new Morphia();
morphia.map(District).map(Contact).map(Address);
District district=new District();
district.setName(jTextField2.getText());
district.setType(jTextField3.getText());
Address address=new Address();
address.setCity(jTextField11.getText());
address.setStreet(jTextField10.getText());
address.setZipcode(jTextField9.getText());
....
Datastore ds=morphia.createDatastore(mongo, "rcfdb");
ds.save(district);
I want if the user doesnt fill the Name field in the Form, then this field is not written in the MongoDB.(now I see the field i.e Name with null value) I have tried to do that but that didnt help me:
....
if(jTextField4.getText()!="")
{
contact.setName(jTextField4.getText());
}
....
could you please help me to do this job?
thanks
Use String#equals to compare String content. The == operator compares object references. JTextField#getText returns a different String object compared to the interned one "" being compared so the field value for the Entity contact is never set.
if (jTextField4.getText().equals("")) {
contact.setName(jTextField4.getText());
}
One can disable storing of null values in mongo by using Datastore.getMapper().getOptions().setStoreNulls(false);

Categories

Resources