Hibernate #OneToMany #ManyToOne inserting into multiple tables - java

CREATE TABLE `Policy` (
`policyId` int(11) NOT NULL AUTO_INCREMENT,
`policyName` varchar(30) NOT NULL,
`roleId` int(11) NOT NULL,
PRIMARY KEY (`policyId`)
CONSTRAINT `policy_ibfk_1` FOREIGN KEY (`roleId`) REFERENCES `Role` (`roleId`) ON DELETE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `Role` (
`roleId` int(11) NOT NULL AUTO_INCREMENT,
`rolename` varchar(30) NOT NULL,
`roleDescription` varchar(100) DEFAULT NULL,
PRIMARY KEY (`roleId`),
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8;
I have a 1-Many mapping for the Role-Policy table described and the POJO as follows
#Entity
#Table(name="policy")
public class AWSPolicy implements Serializable{
#Id
#GeneratedValue
#Column(name = "policyId")
private int policyId;
#Column(name = "policyName")
private String policyName;
#ManyToOne
#JoinColumn(name="roleId")
private Role role;
public AWSRole getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public int getPolicyId() {
return policyId;
}
public void setPolicyId(int policyId) {
this.policyId = policyId;
}
public String getPolicyName() {
return policyName;
}
public void setPolicyName(String policyName) {
this.policyName = policyName;
}
}
#Entity
#Table(name="role")
public class Role implements Serializable{
#Column(name = "rolename")
private String rolename;
#Id
#GeneratedValue
#Column(name = "roleId")
private int roleId;
#Column(name = "roleDescription")
private String roleDescription;
#OneToMany(cascade=CascadeType.PERSIST, mappedBy = "role")
private Set<AWSPolicy> policies;
public Set<AWSPolicy> getPolicies() {
return policies;
}
public void setPolicies(Set<AWSPolicy> policyList) {
this.policies = policyList;
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public String getRoleDescription() {
return roleDescription;
}
public void setRoleDescription(String roleDescription) {
this.roleDescription = roleDescription;
}
}
The issue is that when I try to insert into the table , it inserts only into the Role table but not the policy table. Can someone help me with this.
Role role = new Role();
Set<Policy> policyList = new HashSet<Policy>();
Policy policy = new Policy();
policy.setPolicyName("uberpolicy");
policyList.add(policy);
role.setRolename("uberrole");
role.setRoleDescription("uberrole");
role.setPolicies(policyList);
Session session = getSessionFactory().getCurrentSession();
session.save(role);

May be this example will help you
http://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/
http://viralpatel.net/blogs/hibernate-one-to-many-annotation-tutorial/
Can you please remove cascade=CascadeType.PERSIST and try.
Can you please write output of you query so I can help you.

I tried the code that you post. I see the insert queries being executed on the ROLE and POLICY tables but the value in roleId column of the POLICY table is null. This is because you have set the role object in the policy instance. You have to set both ends of a relationship.
The below code should update the foreign key value
Role role = new Role();
Set<Policy> policyList = new HashSet<Policy>();
Policy policy = new Policy();
policy.setPolicyName("uberpolicy");
policy.setRole(role); //Set the role object in the policy through a setter.
policyList.add(policy);
role.setRolename("uberrole");
role.setRoleDescription("uberrole");
role.setPolicies(policyList);
Session session = getSessionFactory().getCurrentSession();
session.save(role);

Below is the fix
#Entity
#Table(name="cas_aws_role")
public class AWSRole implements Serializable{
#Column(name = "casAWSRolename")
private String casAWSRolename;
#Id
#GeneratedValue
#Column(name = "casAWSRoleId")
private int casAWSRoleId;
#Column(name = "casAWSRoleDisplayName")
private String casAWSRoleDisplayName;
#OneToMany(cascade=CascadeType.ALL)
#JoinColumn(name="casAWSRoleId")
private Set<AWSPolicy> policies = new HashSet<AWSPolicy>();
// method to manage the bidirectional association
public void addToPolicies(AWSPolicy awsPolicy) {
this.policies.add(awsPolicy);
awsPolicy.setAWSRole(this);
}
#ManyToOne
#JoinColumn(name="casAWSRolesetId")
private AWSRoleset awsRoleset;
public AWSRoleset getAWSRoleset() {
return awsRoleset;
}
public void setAWSRoleset(AWSRoleset awsRoleset) {
this.awsRoleset = awsRoleset;
}
public Set<AWSPolicy> getPolicies() {
return policies;
}
public void setPolicies(Set<AWSPolicy> policyList) {
this.policies = policyList;
}
public int getCasAWSRoleId() {
return casAWSRoleId;
}
public void setCasAWSRoleId(int casAWSRoleId) {
this.casAWSRoleId = casAWSRoleId;
}
public String getCasAWSRolename() {
return casAWSRolename;
}
public void setCasAWSRolename(String casAWSRolename) {
this.casAWSRolename = casAWSRolename;
}
public String getCasAWSRoleDisplayName() {
return casAWSRoleDisplayName;
}
public void setCasAWSRoleDisplayName(String casAWSRoleDisplayName) {
this.casAWSRoleDisplayName = casAWSRoleDisplayName;
}
}
#Entity
#Table(name="cas_aws_policy")
public class AWSPolicy implements Serializable{
#Id
#GeneratedValue
#Column(name = "casAWSPolicyId")
private int casAWSPolicyId;
#Column(name = "casAWSPolicyName")
private String casAWSPolicyName;
#ManyToOne
#JoinColumn(name="casAWSRoleId")
private AWSRole awsRole;
public AWSRole getAWSRole() {
return awsRole;
}
public void setAWSRole(AWSRole awsRole) {
this.awsRole = awsRole;
}
public int getCasAWSPolicyId() {
return casAWSPolicyId;
}
public void setCasAWSPolicyId(int casAWSPolicyId) {
this.casAWSPolicyId = casAWSPolicyId;
}
public String getCasAWSPolicyName() {
return casAWSPolicyName;
}
public void setCasAWSPolicyName(String casAWSPolicyName) {
this.casAWSPolicyName = casAWSPolicyName;
}
}

Related

Spring Boot With Hibernate: Unknown column 'book0_.AuthorN' in 'field list'

I need some help with this spring Boot Application with Hibernate. I am trying to get data from the database and for some reason some reason, I keep getting this error message Unknown column 'book0_.AuthorN' in 'field list' I know that there is a column in the Book Table call AuthorN, but I keep getting the error message. It also does the Same thing for ISBN in the Book Table.
Here is MySQL Script.
CREATE TABLE Product
(
ProductID INT NOT NULL
PRIMARY KEY (ProductID)
) ENGINE = innoDB;
CREATE TABLE Author
(
AuthorNum INT NOT NULL
PRIMARY KEY (AuthorNum)
) ENGINE = innoDB;
CREATE TABLE Book
(
BookNum INT NOT NULL,
AuthorN INT NOT NULL,
PRIMARY KEY (BookNum),
CONSTRAINT FOREIGN KEY (BookNum) REFERENCES Product (ProductID),
CONSTRAINT FOREIGN KEY (AuthorN) REFERENCES Author(AuthorNum)
) ENGINE = innoDB;
CREATE TABLE Image
(
ImageNum INT NOT NULL AUTO_INCREMENT,
ProductImgID INT NOT NULL,
PRIMARY KEY (ImageNum),
CONSTRAINT FOREIGN KEY (ProductImgID) REFERENCES Product(ProductID)
) ENGINE = innoDB;
Product.class
#Entity
#Table(name = "Product")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#NotNull(message = "Product id is required")
#Column(name = "ProductID")
public Long getProductID() {
return productID;
}
public void setProductID(Long productID) {
this.productID = productID;
}
#OneToMany(mappedBy = "product")
public List<Image> getImage() {
return image;
}
public void setImage(List<Image> image) {
this.image = image;
}
#NotNull(message = "Product name is required")
#Column(name = "ProductName")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
#NotNull(message = "Product description is required")
#Column(name = "Description")
public String getProductDisc() {
return productDisc;
}
public void setProductDisc(String productDisc) {
this.productDisc = productDisc;
}
#NotNull(message = "Product type is required")
#Column(name = "Type")
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
#Null
#Column(name = "Price")
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
#NotNull(message = "Product release date is required")
#Column(name = "ReleaseDate")
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
The Book.class
#Entity
#Table(name = "Book")
public class Book extends Product{
#NotNull(message = "Book number is required")
#Column(name = "BookNum")
public int getBookNum() {
return bookNum;
}
public void setBookNum(int bookNum) {
this.bookNum = bookNum;
}
#ManyToOne()
#JoinColumn(name = "AuthorN")
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
#NotNull(message = "Book ISBN is required")
#Column(name = "ISBN")
public String getBookISBN() {
return bookISBN;
}
public void setBookISBN(String bookISBN) {
this.bookISBN = bookISBN;
}
}
Author.class
#Entity
#Table(name = "Author")
public class Author {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#NotNull(message = "Author id is required")
#Column(name = "AuthorNum")
public int getAuthorNum() {
return authorNum;
}
public void setAuthorNum(int authorNum) {
this.authorNum = authorNum;
}
#OneToMany(mappedBy = "author")
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
#NotNull(message = "Author name is required")
#Column(name = "AuthorName")
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
#Null
#Column(name = "AboutAuthor")
public String getAboutAuthor() {
return aboutAuthor;
}
public void setAboutAuthor(String aboutAuthor) {
this.aboutAuthor = aboutAuthor;
}
}
BookRepository.class
#Repository
public interface BookRepository extends CrudRepository<Book, Long> {
}
BookService.class
#Service
public class BookService {
private BookRepository repository;
#Autowired
public BookService(BookRepository repository) {
this.repository = repository;
}
public List<Image> getImage() {
List<Image> images = new ArrayList<>();
List<Book> products = (List<Book>) repository.findAll();
return new ArrayList<>();
}
}
Debug SQL Query From Hibernate
Hibernate:
/* select
generatedAlias0
from
Book as generatedAlias0 */ select
book0_.ProductID as ProductI2_2_,
book0_.ReleaseDate as ReleaseD3_2_,
book0_.Price as Price4_2_,
book0_.Description as Descript5_2_,
book0_.ProductName as ProductN6_2_,
book0_.Type as Type7_2_,
book0_.AuthorN as AuthorN10_2_,
book0_.ISBN as ISBN8_2_,
book0_.BookNum as BookNum9_2_
from
Product book0_
where
book0_.DTYPE='Book'
Why is Hibernate Selecting from the Product Table And not From the Book Table?
Is there a way how to solve this problem?

JPA system exception error accesing field

I'm trying to implement a unidirectional many to many relationship between entities with spring+JPA.
After a few tries changing hibernate versions I don't know whats the cause
Caused by: org.springframework.orm.jpa.JpaSystemException: Error accessing field [private java.lang.Integer com.uca.refactor2.model.Achievement.id] by reflection for persistent property [com.uca.refactor2.model.Achievement#id] : 1; nested exception is org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.lang.Integer com.uca.refactor2.model.Achievement.id] by reflection for persistent property [com.uca.refactor2.model.Achievement#id] : 1
User.java
#Entity
#Table(name="USER")
public class User implements Serializable {
private static final long serialVersionUID = 4402583037980335445L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String firstName;
private String lastName;
#Column(unique = true)
private String username;
private String password;
#Enumerated(EnumType.STRING)
private UserType userType;
#OneToMany(cascade=CascadeType.ALL, mappedBy="joinedUserAchievementId.user")
private List<JoinedUserAchievement> joinedUserAchievementList = new ArrayList<JoinedUserAchievement>();
public User() {}
public User(Integer id) {
this.id = id;
}
public User(String username, String firstName, String lastName,
String password, UserType userType) {
this.username = username;
this.firstName = firstName;
this.lastName = lastName;
this.password = password;
this.userType = userType;
}
public List<JoinedUserAchievement> getAllAchievement() {
return joinedUserAchievementList;
}
public void addAchievement(Achievement achievement) {
// Notice a JoinedUserAchievement object
Date dateOfAcquisition = new Date();
JoinedUserAchievement joinedUserAchievement = new JoinedUserAchievement(new JoinedUserAchievement.JoinedUserAchievementId(this, achievement),dateOfAcquisition );
joinedUserAchievement.setAchievementId(achievement.getId());
joinedUserAchievementList.add(joinedUserAchievement);
}
//set and gets
JoinedUserAchievement.java
#Entity
#Table(name="USER_ACHIEVEMENT")
public class JoinedUserAchievement {
public JoinedUserAchievement() {}
public JoinedUserAchievement(JoinedUserAchievementId joinedUserAchievementId, Date dateOfAcquisition) {
this.joinedUserAchievementId = joinedUserAchievementId;
this.dateOfAcquisition = dateOfAcquisition;
}
#ManyToOne(targetEntity = Achievement.class)
#JoinColumn(name="id", insertable=false, updatable=false)
private Integer achievementId;
private Date dateOfAcquisition;
public String getDate() {
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = dateOfAcquisition;
return dateFormat.format(date);
}
public Integer getAchievementId() {
return achievementId;
}
public void setAchievementId(Integer achievementId) {
this.achievementId = achievementId;
}
#EmbeddedId
private JoinedUserAchievementId joinedUserAchievementId;
// required because JoinedUserAchievments contains composite id
#Embeddable
public static class JoinedUserAchievementId implements Serializable {
/**
*
*/
private static final long serialVersionUID = -9180674903145773104L;
#ManyToOne
#JoinColumn(name="USER_ID")
private User user;
#ManyToOne
#JoinColumn(name="ACHIEVEMENT_ID")
private Achievement achievement;
// required no arg constructor
public JoinedUserAchievementId() {}
public JoinedUserAchievementId(User user, Achievement achievement) {
this.user = user;
this.achievement = achievement;
}
public JoinedUserAchievementId(Integer userId, Integer achievementId) {
this(new User(userId), new Achievement(achievementId));
}
public User getUser() {
return user;
}
public Achievement getAchievement() {
return achievement;
}
public void setUser(User user) {
this.user = user;
}
public void setAchievement(Achievement achievement) {
this.achievement = achievement;
}
#Override
public boolean equals(Object instance) {
if (instance == null)
return false;
if (!(instance instanceof JoinedUserAchievementId))
return false;
final JoinedUserAchievementId other = (JoinedUserAchievementId) instance;
if (!(user.getId().equals(other.getUser().getId())))
return false;
if (!(achievement.getId().equals(other.getAchievement().getId())))
return false;
return true;
}
#Override
public int hashCode() {
int hash = 7;
hash = 47 * hash + (this.user != null ? this.user.hashCode() : 0);
hash = 47 * hash + (this.achievement != null ? this.achievement.hashCode() : 0);
return hash;
}
}
}
Achievement.java
#Entity
#Table(name="ACHIEVEMENT")
public class Achievement implements Serializable{
private static final long serialVersionUID = 7747630789725422177L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer points;
public Achievement() {
}
public Achievement(String name, Integer points) {
this.name = name;
this.points = points;
}
public Achievement(Integer id) {
this.id = id;
}
//set and gets
I've also tried to make this relationship bidirectional and it didn't work, so I may be missing something
Also before this I had achievement objects instead of achievementId on joinedUserAchievement, it worked but I think its not what I need, I don't need to get every achievement object always, with only the id is fine.
From the docs:
Relationship mappings defined within an embedded id class are not supported
You should put the ids only in JoinedUserAchievementId, and put User and Achievement associations in JoinedUserAchievement directly like so:
public class JoinedUserAchievementId {
private Long userId;
private Long achievementId;
...
}
public class JoinedUserAchievement {
#EmbeddedId
private JoinedUserAchievementId joinedUserAchievementId;
#ManyToOne
#MapsId("userId")
#JoinColumn(name = "USER_ID")
private User user;
#ManyToOne(optional = false, fetch = LAZY)
#MapsId("achievementId")
#JoinColumn(name = "ACHIEVEMENT_ID")
private Achievement achievement;
//if you absolutely need to map the achievement_id column here as well
//note that it will already be mapped to joinedUserAchievementId.achievementId
#Column(name = "ACHIEVEMENT_ID", insertable=false, updatable=false)
private Long achievementId;
...
}
Remember to update the User.joinedUserAchievementList mapping to mappedBy="user".

Hibernate Annotations Perform Inner Join

Hello I have just started learning hibernate. Please correct me where I am doing mistake. I want do a one-to-many relationship between two tables using a join table using hibernate annotations.
create table assembly
(
assembly_id serial primary key,
number text,
user_id int
);
create table assembly_properties
(
property_id serial primary key,
property_name text,
property_type text
);
create table assembly_properties_mapping
(
mapping_id serial primary key,
assembly_id int,
property_id int,
property_value text,
CONSTRAINT FK_assembly_id FOREIGN KEY (assembly_id) REFERENCES assembly(assembly_id),
CONSTRAINT FK_property_id FOREIGN KEY (property_id) REFERENCES assembly_properties(property_id)
);
I have created these three table in postgres sql database. Below is my Assembly.class
package com.development.wrapper;
#Entity
#Table(name = "assembly")
public class Assembly {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "assembly_id")
private int assembly_id;
#Column(name = "number")
private String number;
#Column(name ="UserID")
private int userId;
#Column
#ElementCollection(targetClass = AssemblyProperties.class)
private Set<AssemblyProperties> assembly_properties;
public int getAssembly_id() {
return assembly_id;
}
public void setAssembly_id(int assembly_id) {
this.assembly_id = assembly_id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
#OneToMany(targetEntity = AssemblyProperties.class, cascade = CascadeType.ALL)
#JoinTable(name = "assembly_properties_mapping", joinColumns = { #JoinColumn(name = "assembly_id") }, inverseJoinColumns = { #JoinColumn(name = "property_id") })
public Set<AssemblyProperties> getAssembly_properties() {
return assembly_properties;
}
public void setAssembly_properties(Set<AssemblyProperties> assembly_properties) {
this.assembly_properties = assembly_properties;
}
}
Below is AssemblyProperties.class
package com.development.wrapper;
#Entity
#Table(name = "assembly_properties")
public class AssemblyProperties {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "property_id")
private int property_id;
#Column(name = "property_name")
private String property_name;
#Column(name = "property_type")
private String property_type;
public int getProperty_id() {
return property_id;
}
public void setProperty_id(int property_id) {
this.property_id = property_id;
}
public String getProperty_name() {
return property_name;
}
public void setProperty_name(String property_name) {
this.property_name = property_name;
}
public String getProperty_type() {
return property_type;
}
public void setProperty_type(String property_type) {
this.property_type = property_type;
}
}
When I am trying to load data in database table as given below I am getting an error Failed to create sessionFactory object.org.hibernate.MappingException: Could not determine type for: com.development.wrapper.AssemblyProperties, at table: Assembly_assembly_properties, for columns: [org.hibernate.mapping.Column(assembly_properties)]
Exception in thread "main" java.lang.ExceptionInInitializerError
below is code I am trying to run
public class Test
{
SessionFactory factory;
public Test() throws Exception
{
try
{
factory = new AnnotationConfiguration().configure().
addPackage("com.development.wrapper"). //add package if used.
addAnnotatedClass(Assembly.class).buildSessionFactory();
}
catch (Throwable ex)
{
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public Integer addClass(Assembly assembly)
{
Session session = factory.openSession();
Transaction tx = null;
Integer assemblyid = null;
try
{
tx = session.beginTransaction();
assemblyid = (Integer) session.save(assembly);
System.out.println(assemblyid);
tx.commit();
}
catch (HibernateException e)
{
if (tx != null)
tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
return assemblyid;
}
public static void main(String[] args) throws Exception {
Set<AssemblyProperties> assemblyProperties = new HashSet<AssemblyProperties>();
AssemblyProperties ass=new AssemblyProperties();
ass.setProperty_name("xx");
ass.setProperty_type("List");
assemblyProperties.add(ass);
Assembly assembly =new Assembly();
assembly.setAssembly_properties(assemblyProperties);
assembly.setNumber("aaa");
assembly.setUserId(1);
Test test=new Test();
test.addClass(assembly);
}
}
Please help me to resolve this error/ Thanks in advance.
Hibernate can't handle when the annotations for public setters and private fields are mixed in one class.
A possible solution would be to make all of your annotations at the public setters instead of mixing it between the private fields and the public setters, that way you can avoid the case where there are annotations both at public and private access modifiers.
Your annotations are conflicting. this:
#Column
#ElementCollection(targetClass = AssemblyProperties.class)
private Set<AssemblyProperties> assembly_properties;
and this:
#OneToMany(targetEntity = AssemblyProperties.class, cascade = CascadeType.ALL)
#JoinTable(name = "assembly_properties_mapping", joinColumns = { #JoinColumn(name = "assembly_id") }, inverseJoinColumns = { #JoinColumn(name = "property_id") })
public Set<AssemblyProperties> getAssembly_properties() {
return assembly_properties;
}
just remove first annotaions over private field (assembly_properties).

Hibernate annotation referencedcolumnname does not work , referencedcolumnname is assigned primary key of the another entity automatically

in enthesaplasmaek entity, i made relationship as below with my two entities, EntHesaplasma and EntHesaplasmaek
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="hesaplasmaekid",referencedColumnName="carihareketid",insertable=false,updatable=false)
#Where(clause = "enthesaplasma.evraktip='EK'")
public EntHesaplasma getEnthesaplasma() {
return enthesaplasma;
}
when i run the below hql , hibernate makes a relationship between hesaplasmaekid and hesaplasmaid (primary key (#Id) of enthesaplasma entity). But the correct relationship should be between carihareketid in enthesaplasma entity and enthesaplasmaekid in the enthesaplasmaek entity.
select hs.hesaplasmaid,hs.carihareketid,ek.hesaplasmaekid,hs.hesaplasmano,ek.aciklama from EntHesaplasmaek ek left join ek.enthesaplasma hs
Result of the query (from Hibernate Query Editor in eclipse)
how can i correct this error ? thanks.
My entities are below
EntHesaplasma entity
#Entity
#Table(name = "XOZ_HESAPLASMA")
public class EntHesaplasma {
Integer hesaplasmaid;
#Transient
EntCariHareketler carihareket;
#Resolvable(colName = "Hesaplaşma No",formatter=FormatterInteger.class)
Integer hesaplasmano;
Integer hesaplasmagrupid;
Date datecreated;
Integer carihareketid;
String evraktip;
Boolean isactive;
Double meblag;
EntHesaplasmagrup enthesaplasmagrup;
EntHesaplasmaek enthesaplasmaek;
#Id
#GeneratedValue
#Column(name = "hesaplasmaid", unique = true, nullable = false)
public Integer getHesaplasmaid() {
return hesaplasmaid;
}
public void setHesaplasmaid(Integer hesaplasmaid) {
this.hesaplasmaid = hesaplasmaid;
}
#Column(name = "datecreated")
public Date getDatecreated() {
return datecreated;
}
public void setDatecreated(Date datecreated) {
this.datecreated = datecreated;
}
#Column(name = "hesaplasmano")
public Integer getHesaplasmano() {
return hesaplasmano;
}
//#OneToOne(fetch= FetchType.LAZY)
//#JoinColumn(name="carihareketid")
#Transient
public EntCariHareketler getCarihareket() {
return carihareket;
}
public void setCarihareket(EntCariHareketler carihareket) {
this.carihareket = carihareket;
}
public void setHesaplasmano(Integer hesaplasmano) {
this.hesaplasmano = hesaplasmano;
}
#Column(name = "carihareketid")
public Integer getCarihareketid() {
return carihareketid;
}
public void setCarihareketid(Integer carihareketid) {
this.carihareketid = carihareketid;
}
#Column(name="isactive")
public Boolean getIsactive() {
return isactive;
}
public void setIsactive(Boolean isactive) {
this.isactive = isactive;
}
#Column(name="meblag")
public Double getMeblag() {
return meblag;
}
public void setMeblag(Double meblag) {
this.meblag = meblag;
}
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="hesaplasmagrupid")
public EntHesaplasmagrup getEnthesaplasmagrup() {
return enthesaplasmagrup;
}
public void setEnthesaplasmagrup(EntHesaplasmagrup enthesaplasmagrup) {
this.enthesaplasmagrup = enthesaplasmagrup;
}
#Column(name="hesaplasmagrupid",insertable=false,updatable=false)
public Integer getHesaplasmagrupid() {
return hesaplasmagrupid;
}
public void setHesaplasmagrupid(Integer hesaplasmagrupid) {
this.hesaplasmagrupid = hesaplasmagrupid;
}
#Column(name="evraktip")
public String getEvraktip() {
return evraktip;
}
public void setEvraktip(String evraktip) {
this.evraktip = evraktip;
}
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="carihareketid",referencedColumnName="hesaplasmaekid",insertable=false,updatable=false)
#Where(clause = "evraktip='EK'")
public EntHesaplasmaek getEnthesaplasmaek() {
return enthesaplasmaek;
}
public void setEnthesaplasmaek(EntHesaplasmaek enthesaplasmaek) {
this.enthesaplasmaek = enthesaplasmaek;
}
}
EntHesaplasmaek entity
#Entity
#Table(name = "XOZ_HESAPLASMAEK")
public class EntHesaplasmaek {
Integer hesaplasmaekid;
#Resolvable(colName="Bakiye",formatter=DoubleFormatter.class)
Double bakiye;
#Resolvable(colName="Açıklama")
String aciklama;
Integer konuid;
Boolean boolzamanlanmis;
Integer zamanid;
Date datecreated;
#Resolvable(colName="Tarih",formatter=DateFormatterTbl.class)
Date evraktarih;
#Resolvable(colName="Hesaplasma No",formatter=FormatterInteger.class)
#Transient
Integer hesaplasmano;
Integer hesaplasmagrupid;
EntHesaplasmagrup enthesaplasmagrup;
EntHesaplasma enthesaplasma;
#Id
#GeneratedValue
#Column(name = "hesaplasmaekid", unique = true, nullable = false)
public Integer getHesaplasmaekid() {
return hesaplasmaekid;
}
public void setHesaplasmaekid(Integer hesaplasmaekid) {
this.hesaplasmaekid = hesaplasmaekid;
}
#Column(name="bakiye")
public Double getBakiye() {
return bakiye;
}
public void setBakiye(Double bakiye) {
this.bakiye = bakiye;
}
#Column(name="aciklama")
public String getAciklama() {
return aciklama;
}
public void setAciklama(String aciklama) {
this.aciklama = aciklama;
}
#Column(name="konuid")
public Integer getKonuid() {
return konuid;
}
public void setKonuid(Integer konuid) {
this.konuid = konuid;
}
#Column(name="boolzamanlanmis")
public Boolean getBoolzamanlanmis() {
return boolzamanlanmis;
}
public void setBoolzamanlanmis(Boolean boolzamanlanmis) {
this.boolzamanlanmis = boolzamanlanmis;
}
#Column(name="zamanid")
public Integer getZamanid() {
return zamanid;
}
public void setZamanid(Integer zamanid) {
this.zamanid = zamanid;
}
#Column(name="datecreated")
public Date getDatecreated() {
return datecreated;
}
public void setDatecreated(Date datecreated) {
this.datecreated = datecreated;
}
#Column(name="evraktarih")
public Date getEvraktarih() {
return evraktarih;
}
public void setEvraktarih(Date evraktarih) {
this.evraktarih = evraktarih;
}
#Transient
public Integer getHesaplasmano() {
return hesaplasmano;
}
public void setHesaplasmano(Integer hesaplasmano) {
this.hesaplasmano = hesaplasmano;
}
#Column(name="hesaplasmagrupid",insertable=false,updatable=false)
public Integer getHesaplasmagrupid() {
return hesaplasmagrupid;
}
public void setHesaplasmagrupid(Integer hesaplasmagrupid) {
this.hesaplasmagrupid = hesaplasmagrupid;
}
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="hesaplasmagrupid")
public EntHesaplasmagrup getEnthesaplasmagrup() {
return enthesaplasmagrup;
}
public void setEnthesaplasmagrup(EntHesaplasmagrup enthesaplasmagrup) {
this.enthesaplasmagrup = enthesaplasmagrup;
}
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="hesaplasmaekid",referencedColumnName="carihareketid",insertable=false,updatable=false)
#Where(clause = "enthesaplasma.evraktip='EK'")
public EntHesaplasma getEnthesaplasma() {
return enthesaplasma;
}
public void setEnthesaplasma(EntHesaplasma enthesaplasma) {
this.enthesaplasma = enthesaplasma;
}
}
A bit late, but got into the same problem.
It's not a bug that you can't set up bidirectional relation, one side need to use JoinColumn, another map it via mappedBy. So yes..the solution here is correct!
I found the explanation here:
How do I join tables on non-primary key columns?
this seems a bug in hibernate. but i solved my problem with mappedby annotation.
i added a field to my enthesaplasma entity as below. i defined the relationship in this entity.
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="carihareketid",insertable=false,updatable=false)
public EntHesaplasmaek getEnthesaplasmaek() {
return enthesaplasmaek;
}
public void setEnthesaplasmaek(EntHesaplasmaek enthesaplasmaek) {
this.enthesaplasmaek = enthesaplasmaek;
}
i updated my other entity as below.
#OneToOne(fetch=FetchType.LAZY,mappedBy="enthesaplasmaek")
public EntHesaplasma getEnthesaplasma() {
return enthesaplasma;
}
public void setEnthesaplasma(EntHesaplasma enthesaplasma) {
this.enthesaplasma = enthesaplasma;
}
Addition info and question : in this link, it is said that referencedcolumnname is used, when there is a composite P.K in an entity. is this correct ?
(from What is referencedColumnName used for in JPA? )
Quoting API on referencedColumnName:
The name of the column referenced by this foreign key column.
Default (only applies if single join column is being used): The same name as the primary key column of the referenced table.
Q/A
Where this would be used?
When there is a "composite PK" in referenced table, then you need to
specify column name you are referencing.

Hibernate issue " Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1"

I'm using Jersey + spring + hibernate4.17 to develop api system; The problem is if the cleaFields is called twice at same time, the 2nd call will throw an exception as below,
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:81)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.checkRowCounts(BatchingBatch.java:133)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:110)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:101)
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:149)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:162)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:357)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:280)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
The clearFields method in the Controller,
#Transactional(isolation=Isolation.REPEATABLE_READ)
public void clearFields(Integer userId) {
User user = this.userDao.get(userId);
user.getFields().clear();
userDao.flush(); //call the current session.flush(); this line can throw exception.
}
User Entity class
#Entity
#Table(name="users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id", unique = true, nullable = false)
private int userId;
#OneToMany(mappedBy = "user", cascade = { CascadeType.ALL }, targetEntity = UserProfile.class, fetch = FetchType.LAZY, orphanRemoval=true)
#OrderBy("id")
private List<UserProfile> fields = new ArrayList<UserProfile>();
public User() {
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public List<UserProfile> getFields() {
return fields;
}
public void setFields(List<UserProfile> fields) {
this.fields = fields;
}
}
UserProfile class,
#Entity
#Table(name="user_profiles")
public class UserProfile implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="field_name")
private String fieldName;
#ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
#JoinColumn(name="user_id")
private User user;
private String value;
public UserProfile() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFieldName() {
return this.fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
I did some research, the root cause is if the 2nd calling get some fields, and before delete them, the 1st calling already delete all fields from database.
In another word, the 2nd calling try to delete some records which already were deleted by others.
How can I solve the problem?

Categories