I am trying to insert into many to many relationship using hibernate but I am getting this error.
2014-04-24 14:50:47,820 ERROR [BasicPropertyAccessor.java:118] : IllegalArgumentException in class: com.jellboi.maniartyre.entities.AbstractEntity, setter method of property: pkey
2014-04-24 14:50:47,827 ERROR [BasicPropertyAccessor.java:122] : expected type: java.lang.Long, actual value: org.hibernate.id.IdentifierGeneratorHelper$2
Apr 24, 2014 2:55:25 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet applicationController threw exception
java.lang.IllegalArgumentException: java.lang.ClassCastException#17d66f6
at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
Here is the code that I am trying.
VehicleProduct class
#Entity
#Table(name="m_vehicle_product")
#AssociationOverrides({
#AssociationOverride(name = "pk.vehicle",
joinColumns = #JoinColumn(name = "vehicle_id")),
#AssociationOverride(name = "pk.product",
joinColumns = #JoinColumn(name = "product_id")),
})
public class VehicleProduct extends AbstractEntity{
private String service;
private VehicleProductId pk = new VehicleProductId();
#Column(name = "service")
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
#EmbeddedId
public VehicleProductId getPk() {
return pk;
}
public void setPk(VehicleProductId pk) {
this.pk = pk;
}
#Transient
public Product getProduct(){
return getPk().getProduct();
}
public void setProduct(Product product){
getPk().setProduct(product);
}
#Transient
public Vehicle getVehicle(){
return getPk().getVehicle();
}
public void setVehicle(Vehicle vehicle){
getPk().setVehicle(vehicle);
}
}
VehicleProductId Class
#Embeddable
public class VehicleProductId implements java.io.Serializable {
private Vehicle vehicle;
private Product product;
#ManyToOne
public Vehicle getVehicle() {
return vehicle;
}
public void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
}
#ManyToOne
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
}
And this is how I am Inserting.
for(int i=0;i<jobid.length;i++){
product = productService.findByPkey(jobid[i]);
vehicleProduct.setProduct(product);
vehicleProduct.setService(jobdesc[i]);
pkey2 = vehicleProductService.save(vehicleProduct);
}
Please guide me on this. Trying since hours to solve this problem.
EDIT
#MappedSuperclass
public class AbstractEntity implements IEntity, Serializable{
private static final long serialVersionUID = 1L;
private Long pkey;
private Boolean deleted;
private String creator;
private Date created;
private String changer;
private Date changed;
private Long version;
#Id
#GeneratedValue
#Column(name="pkey")
public Long getPkey() {
return pkey;
}
public void setPkey(Long pkey) {
this.pkey = pkey;
}
#Column(name="deleted")
#XmlTransient
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
#Column(name="creator")
public String getCreator() {
return creator;
}
}........
It contains all of these getter and setters.
Your main problem is this:
2014-04-24 14:50:47,820 ERROR [BasicPropertyAccessor.java:118] : IllegalArgumentException in class: com.jellboi.maniartyre.entities.AbstractEntity, setter method of property: pkey
2014-04-24 14:50:47,827 ERROR [BasicPropertyAccessor.java:122] : expected type: java.lang.Long, actual value: org.hibernate.id.IdentifierGeneratorHelper$2
If you look at your code, you have an #Id defined on your AbstractEntity and an #EmbeddedId on your VehicleProduct
I am not sure how your database table is supposed to look, but it will seem to include the columns in AbstractEntity as well as those defined in VehicleProduct. If the columns are not meant to be there, then you shouldn't inherit from AbstractEntity. If they were meant to be there, then consider making the #EmbeddedId into an #Embedded and enforce a unique constraint for the business key.
2014-04-24 14:50:47,820 ERROR [BasicPropertyAccessor.java:118] : IllegalArgumentException in class: com.jellboi.maniartyre.entities.AbstractEntity, setter method of property: pkey
2014-04-24 14:50:47,827 ERROR [BasicPropertyAccessor.java:122] : expected type: java.lang.Long, actual value: org.hibernate.id.IdentifierGeneratorHelper$2
I do not know it this is your case, but taking a look to your trace I have to say hibernate does not support composite PK's with an identity part
Hibernate Jira composite PK identity part
Related
I have the following setup:
#Entity
#IdClass(MemberAttributePk.class)
public class MemberAttribute {
#Id
#ManyToOne #JoinColumn(name="member_id")
protected Member member;
#Id
protected String name;
private String value;
public MemberAttribute() {}
// get & set
}
And the id class:
public class MemberAttributePk implements Serializable {
protected Member member;
protected String name;
public MemberAttributePk() {}
// get & set
}
I have defined a simple Spring Data repository for MemberAttribute:
#Repository
public interface MemberAttributeRepo extends JpaRepository<MemberAttribute, MemberAttributePk> {
}
Now, all I want to do is persist a member attribute to the database:
public void saveAttribute(Member member, String name, String value) {
MemberAttribute attr = new MemberAttribute(member, name, value);
attributeRepo.save(attr);
}
However, I end up with this server exception:
2016-08-28 00:24:20.673 WARN 5656 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver :
Failed to convert request element: org.springframework.beans.ConversionNotSupportedException:
Failed to convert property value of type [java.lang.Long] to required type [com.example.Member] for property 'member'; nested exception is java.lang.IllegalStateException:
Cannot convert value of type [java.lang.Long] to required type [com.example.Member] for property 'member':
no matching editors or conversion strategy found
Any idea what am I doing wrong?
Thanks!
Simply your code is not JPA compliant. The cause of problem is that you use Member as a part of your PK.
The PK can only be made up of fields of the following Java types
Primitives : boolean , byte , char , int , long , short
java.lang : Boolean , Byte , Character , Integer , Long , Short , String , Enum , StringBuffer
java.math : BigInteger java.sql : Date , Time , Timestamp
java.util : Date , Currency, Locale, TimeZone, UUID
java.net : URI, URL
javax.jdo.spi : PersistenceCapable
This should work:
#Embeddable
public class MemberAttributePk implements Serializable {
#Column(name = "member_id")
protected Long memberId;
#Column(name = "name")
protected String name;
public MemberAttributePk() {}
// get & set
}
#Entity
public class MemberAttribute {
#EmbeddedId
protected MemberAttributePk memberAttributePk;
#ManyToOne
#JoinColumn(name="member_id")
protected Member member;
private String value;
public MemberAttribute() {}
// get & set
}
Or the same with #ClassId
public class MemberAttributePk implements Serializable {
protected Long memberId;
protected String name;
public MemberAttributePk() {}
// get & set
}
#Entity
#IdClass(MemberAttributePk.class)
public class MemberAttribute {
#Id
#Column(name = "member_id")
protected Long memberId;
#Id
#Column(name = "name")
protected String name;
#ManyToOne
#JoinColumn(name="member_id")
protected Member member;
private String value;
public MemberAttribute() {}
// get & set
}
you can try save it using your MemberRepository, because I believe your Member class and MemberAttribute class have a one to many relationship reference, here below is the example
Member class
#Entity
public class Member {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public long id;
#OneToMany(mappedBy = "Member", cascade = CascadeType.ALL)
private Set<MemberAttribute> mMemberAttributes = new HashSet<>();
public void setMemberAttributes(Set<MemberAttribute> mMemberAttributes){
this.mMemberAttributes = mMemberAttributes;
}
public Set<MemberAttribute> getMemberAttributes(){
return mMemberAttributes;
}
// other code
}
MemberRepository class
public interface MemberRepository extends JpaRepository<Member, Long> {
}
code inside your save function
public void saveAttribute(Member member, String name, String value) {
MemberAttribute attr = new MemberAttribute(member, name, value);
member.getMemberAttributes().add(attr);
memberRepository.save(member);
}
I'm facing problem in creating one to one mapping in Hibernate. Following is how i'm trying to achieve it.
Following is my super class for SysEntity
#MappedSuperclass
public class BaseSysEntity {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
#Column(name="sysupdate")
private Date sysupdate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getSysupdate() {
return sysupdate;
}
public void setSysupdate(Date sysupdate) {
this.sysupdate = sysupdate;
}
}
Following class is the entity which will create oneToOne relation ship with "Project"
#Entity
#Table(name="sysproject")
public class SysProject extends BaseSysEntity implements Serializable {
#OneToOne(optional=true, fetch= FetchType.LAZY)
#PrimaryKeyJoinColumns({
#PrimaryKeyJoinColumn(name="sysClientId", referencedColumnName="sysClientId"),
#PrimaryKeyJoinColumn(name="pProject", referencedColumnName="pProject")
})
private Project project;
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
}
Following is Project class:
#Entity
#Table(name = "tproject")
public class Project {
#EmbeddedId
private ProjectID id; // It contains sysClientId and pProject as primary key
#OneToOne(optional=true, mappedBy="project")
private SysProject SysProject;
}
ProjectID Class:
#Embeddable
public class ProjectID implements Serializable{
#Column(name="pProject")
private String project;
#Column(name="sysClientId")
private String sysClientId;
public String getProject() {
return project;
}
public ProjectID(){
this.sysClientId="0";
}
public ProjectID(Integer number){
this();
this.project = number.toString();
}
public void setProject(String project) {
this.project = project;
}
public String getSysClientId() {
return sysClientId;
}
public void setSysClientId(String sysClientId) {
this.sysClientId = sysClientId;
}
}
Exception which i'm getting:
Caused by: org.hibernate.MappingException: broken column mapping for: SysProject.id of: com.spin.integration.dto.Project
at org.hibernate.persister.entity.AbstractPropertyMapping.initPropertyPaths(AbstractPropertyMapping.java:178)
at org.hibernate.persister.entity.AbstractPropertyMapping.initIdentifierPropertyPaths(AbstractPropertyMapping.java:249)
at org.hibernate.persister.entity.AbstractPropertyMapping.initPropertyPaths(AbstractPropertyMapping.java:222)
at org.hibernate.persister.entity.AbstractEntityPersister.initOrdinaryPropertyPaths(AbstractEntityPersister.java:2434)
at org.hibernate.persister.entity.AbstractEntityPersister.initPropertyPaths(AbstractEntityPersister.java:2471)
at org.hibernate.persister.entity.AbstractEntityPersister.postConstruct(AbstractEntityPersister.java:3766)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:451)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:386)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1790)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)
... 18 more
NOTE: This oneToOne mapping is not present at database level (Unfortunately i can't make changes to database).
You can check this solution its working :
One Id of composite key to be referenced in another entity
he's facing the same issue
#OneToOne(optional=true, fetch= FetchType.LAZY)
#JoinColumns({
#JoinColumn(name="sysClientId", referencedColumnName="sysClientId"),
#JoinColumn(name="pProject", referencedColumnName="pProject")
})
Instead of using #PrimaryKeyJoinColumns I had to use #JoinColumns.
I'm facing a problem with Ebean when trying to create Composed Keys (EmbeddedId).
This is a draft of what I have:
#Entity public class EntityA extends Model{
#Id
private String ID;
#OneToMany
private List<EntityB> listEntitesB;
public EntityA(){
ID = UUID.randomUUID();
}
}
#Entity public class EntityB extends Model{
#EmbeddedId
private EntityB_PK ID;
#ManyToOne
#JoinColumn(name="entityA_fk", referencedColumnName="listEntitiesB")
private EntityA entityA;
public EntityB(String entityB_ID){
ID = new EntityB_PK(UUID.randomUUID(), entityB_ID);
}
}
#Embeddable public class EntityB_PK{
private String entityB_ID;
private String entityA_FK_ID;
public EntityB_PK(String entB_ID, String entA_FK_ID){
entityB_ID = entB_ID;
entityA_FK_ID = entA_FK_ID;
}
}
Note: I'm using Ebean 4.1.4 with Java 1.6.
So, this code works well, but there is a perk, which I'm trying to solve - the resultant table in the database looks like this:
entityB_ID [primary]
entityA_FK_ID [primary]
entityA_fk
As you can see that last column is redundant considering the "entityA_FK_ID" column.
What I would like to have?
I would like to be able to tell Ebean to use the column "entityA_FK_ID" for the association #ManyToOne instead of creating it's own column.
To solve this problem we have to:
Map EntityB.entityA to the same column as EntityB.ID.entityA_FK_ID
set 'insertable' and 'updateable' attributes of EntityB.entityA #JoinColumn annotation
Override setter of EntityB.entityA
Here is the code:
EntityA.java:
#Entity
public class EntityA extends Model {
#Id
private String ID;
#OneToMany(mappedBy="entityA")
public List<EntityB> listEntitesB;
public static Finder<String,EntityA> find = new Finder<String,EntityA>(
String.class, EntityA.class
);
public EntityA() {
ID = UUID.randomUUID().toString();
}
public String getID() {
return ID;
}
}
EntityB.java:
#Entity
public class EntityB extends Model {
#EmbeddedId
private EntityB_PK ID;
#ManyToOne
#JoinColumn(name = "entityA_fk_id", insertable = false, updatable = false)
private EntityA entityA;
public EntityA getEntityA() {
return entityA;
}
public void setEntityA(EntityA aEntityA) {
entityA = aEntityA;
ID.entityA_FK_ID = aEntityA.getID();
}
public EntityB(String entityB_ID){
ID = new EntityB_PK(UUID.randomUUID().toString(), entityB_ID);
}
public String getID() {
return ID.entityB_ID;
}
}
EntityB_PK.java:
#Embeddable
public class EntityB_PK implements Serializable {
public String entityB_ID;
#Column(name="entityA_fk_id")
public String entityA_FK_ID;
public EntityB_PK(String entB_ID, String entA_FK_ID){
entityB_ID = entB_ID;
entityA_FK_ID = entA_FK_ID;
}
#Override
public int hashCode() {
return entityB_ID.length() + entityA_FK_ID.length();
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
EntityB_PK b = (EntityB_PK)obj;
if(b==null)
return false;
if (b.entityB_ID.equals(entityB_ID) && b.entityA_FK_ID.equals(entityA_FK_ID)) {
return true;
}
return false;
}
}
I have this Play Model class that I'm trying to modify an object of, and when I want to save it, I get the following exception:
java.lang.RuntimeException: No #javax.persistence.Id field found in class [class models.Contact]
at play.db.ebean.Model._idAccessors(Model.java:39)
at play.db.ebean.Model._getId(Model.java:52)
The class:
#Entity
public class Contact extends Model implements Person {//, Comparable<Contact>{
private Long id;
private Client client;
#Required
private String email;
private String profil_picture;
private Boolean active = new Boolean(true);
private Boolean favorite = new Boolean(false);
#Transient
private Boolean profile_pic_url_init = new Boolean(false);
#Id
#GeneratedValue
public Long getId() {
return id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="client_id")
public Client getClient(){
return client;
}
public void setClient(Client client){
this.client= client;
}
#Column
public Boolean getFavorite() {
return favorite;
}
public void setFavorite(Boolean is_favorite) {
this.favorite = is_favorite;
}
....
}
The code calling the save() method:
List<Contact> contacts_list = current_client.getContacts();
for (Contact c : contacts_list) {
c.setFavorite(false);
c.save();
}
The class actually has an #Id annotation, so any guesses of why this doesn't work? I tried looking it up on google, but couldn't find much about this error. Thanks in advance!
Move #Id annotation to id field instead of its getter.
I'm rather new to Hibernate and it turns out it's not a simple technology to learn... In the project I use hibernate version 4.2.0.CR1. I'm trying to create a base class for all database entities, as they all are supposed to contain some identifier and date of creation. What is weird is that at first, I crated class User and UserPicture without any base class and it worked perfectly fine and now that I added it, even though it's supposed to work just like before, it doesn't o_O and it keeps on throwing some weird exception about my list of pictures, that was not thrown before...
So I keep on getting following stacktrace:
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: User, for columns: [org.hibernate.mapping.Column(profilePicture)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:314)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:292)
at org.hibernate.mapping.Property.isValid(Property.java:239)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:469)
at org.hibernate.mapping.UnionSubclass.validate(UnionSubclass.java:61)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1283)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1734)
at love.commons.database.DBManager.<init>(DBManager.java:28)
at love.commons.database.DBManagerTest.<clinit>(DBManagerTest.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
AbstractEntity:
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractEntity implements Serializable{
private static final long serialVersionUID = 1L;
protected Long id;
protected Date creationDate = new Date();
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.TABLE)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column
#NotNull
#Temporal(TemporalType.DATE)
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}
User:
#Entity
#Table(name="User")
public class User extends AbstractEntity {
private static final long serialVersionUID = 1L;
#Column (unique=true, length=30)
#NotNull
private String login;
#Column (length=32)
#NotNull
private String password;
#NotNull
#Email
#Column (unique=true, length=80)
private String email;
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="owner")
private List<UserPicture> profilePictures = new LinkedList<UserPicture>();
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Transient
public void encryptPassword() {
this.password = md5(password);
}
public List<UserPicture> getProfilePicture() {
return Collections.unmodifiableList(profilePictures);
}
public void addProfilePicture(UserPicture profilePicture) {
profilePicture.setOwner(this);
profilePictures.add(profilePicture);
}
#Transient
private String md5(String input) {
String md5 = null;
if(null == input) return null;
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(input.getBytes(), 0, input.length());
md5 = new BigInteger(1, digest.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5;
}
}
UserPicture:
#Entity
public class UserPicture extends AbstractEntity {
private static final long serialVersionUID = 1L;
#Column(length=734004)
private byte [] picture = null;
#ManyToOne(fetch=FetchType.LAZY)
#Column(name="owner")
#JoinColumn(nullable=false,name="id")
private User owner;
public UserPicture() {
picture = null;
}
public UserPicture(InputStream stream) {
try {
this.picture = new byte[stream.available()];
stream.read(picture);
} catch (IOException e) {
e.printStackTrace();
}
}
public UserPicture(byte [] picture) {
this.picture = picture;
}
public byte[] getPicture() {
return picture;
}
public void setPicture(byte[] picture) {
this.picture = picture;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
So what am I doing wrong? Why do I keep on getting the exception?
AbstractEntity must not be annotated with #Entity and #Inheritance. It must be annotated with #MappedSuperclass. Indeed, this inheritance is only used to inherit common attributes, and that's what MappedSuperclass is for.
The exception you get is caused by the lack of coherence in the position of your mapping annotations. The base superclass annotated the getters, and the subclasses annotate the fields. Hibernate uses the position of the Id annotation to determine the access type of the entity. Since #Id is on a getter, it only considers the annotations placed on getters, and ignores those placed on fields. Put all your annotations either on fields (which I would recommend) or on getters.
Moreover, your getter is badly named. It should be getProfilePictures() and not getProfilePicture().
From Hibernate 5.2 documentation:
By default, the placement of the #Id annotation gives the default
access strategy.
For your case, hibernate will use AccessType.PROPERTY both for UserPicture and User entities hence the exception, to use field mapping strategy, you should define #Access strategy explicitly :
#Entity
#Table(name="User")
#Access( AccessType.FIELD )
public class User extends AbstractEntity {
...
}
#Entity
#Access( AccessType.FIELD )
public class UserPicture extends AbstractEntity {
....
}
I had the same problem, i figured out that hibernate tried to use Parent using properties accessorso i solved the problem by using #Access annotation to force use fields
#Entity
#Table(name = "MyTable")
#Access(AccessType.FIELD)
public class MyEntity{
......
}
you can try to add #ElementCollection mapping above the List declaration.