Reputation: 1437
I am getting weired exception and not able to trace why it so. Please help me here.
I am just using OneToOne mapping with PrimarykeyJoinColumn property.
@Entity
@Table(name="mediashow_user1")
public class UserVO implements Serializable{
private static final long serialVersionUID = 6066636545309839156L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long empid ;
private String email = null;
private String fname = null ;
private String lname = null ;
private String mname = null ;
private String uname = null ;
private String passwd = null ;
private String serctquestion = null ;
private String serctanswer = null ;
private int telephone;
private Timestamp cur_timestamp = null ;
private Timestamp lastvisited_timestamp = null ;
@OneToOne(cascade=CascadeType.ALL)
@PrimaryKeyJoinColumn
private AddressVO addressVO;
@Column(name="empid")
public Long getEmpid() {
return empid;
}
..................
another AddressVO.java
@Entity
@Table(name="mediashow_address1")
@GenericGenerator(name="foreign", strategy = "foreign", parameters={
@Parameter(name="property", value="userVO")
})
public class AddressVO implements Serializable {
private static final long serialVersionUID = -96886746528894662L;
@Id
@GeneratedValue(generator="foreign")
private Long empid;
private String street = null ;
private String zipcode = null ;
private String landmark = null ;
........
}
Transaction transaction = null;
try {
transaction = session.beginTransaction();
AnnotationConfiguration conf = (new AnnotationConfiguration()).configure();
new SchemaExport(conf).create(true, false);
UserVO user = new UserVO();
user.setEmail("[email protected]");
user.setFname("Rahul10");
user.setMname("Bapusaheb10");
user.setLname("Bandgar10");
user.setUname("rahul");
user.setPasswd("rahul");
user.setSerctanswer("baramati");
user.setSerctquestion("What is your birth place name?");
AddressVO address = new AddressVO();
address.setLandmark("Landmark5");
address.setStreet("street4");
address.setZipcode("234344");
int i = 9850;
user.setTelephone(i);
user.setAddressVO(address);
Long id= (Long)session.save(user);
System.out.println("ID::"+id);
transaction.commit();
} catch (HibernateException e) {
System.out.println("Exception:"+e.getMessage());
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
and I am getting following exception while running the above code.
alter table mediashow_user1 drop foreign key FK5FD5BCE8801495D
drop table if exists mediashow_address1
drop table if exists mediashow_user1
create table mediashow_address1 (
empid bigint not null,
landmark varchar(255),
street varchar(255),
zipcode varchar(255),
primary key (empid)
)
create table mediashow_user1 (
empid bigint not null auto_increment,
cur_timestamp datetime,
email varchar(255),
fname varchar(255),
lastvisited_timestamp datetime,
lname varchar(255),
mname varchar(255),
passwd varchar(255),
serctanswer varchar(255),
serctquestion varchar(255),
telephone integer not null,
uname varchar(255),
primary key (empid)
)
alter table mediashow_user1
add index FK5FD5BCE8801495D (empid),
add constraint FK5FD5BCE8801495D
foreign key (empid)
references mediashow_address1 (empid)
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:521)
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValue(AbstractEntityPersister.java:3867)
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:100)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:450)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:282)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:713)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:701)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:697)
at com.imgshop.run.TestAddIntoLogin.main(TestAddIntoLogin.java:49)
Upvotes: 4
Views: 3141
Reputation: 1
Make this change in your code :
@GenericGenerator(name="foreign", strategy = "foreign", parameters={
@Parameter(name="property", value="user")
})
we need to pass object of the class instead of class name in parameter annotation in its value parameter. Hence there should not be value="userVO" and should be value="user"
Please try and let me know if it works
Upvotes: 0
Reputation: 1235
I faced similar situation and resolved it myself after some experimentation. An important thing to remember here is that when you use foreign
strategy for an ID generator the relationship can't be unidirectional. In your case you need to make two changes(see below).Basically you have set cascade to all for AddressVO @OneToOne(cascade=CascadeType.ALL)
and when you try to save the UserVO this will trigger similar operation for AddressVO. But for AddressVO you set the Id generator strategy as 'foreign' with property userVO
. But you never set the property userVO
in AddressVO so it gets null id and hence the exception. To make this work for you need to do the following changes
1) Add userVO property (getter/setters) to AddressVo and before saving userVo add this object to addressVO in you transaction address.setUserVo(user);
and then call session.save(user);
2)Edit your db schema to reflect the shared primarykey in addressVO as the foreign key constraint is in AddressVo not in UserVO. i.e., change the following
alter table mediashow_user1
add index FK5FD5BCE8801495D (empid),
add constraint FK5FD5BCE8801495D
foreign key (empid)
references mediashow_address1 (empid)
to
alter table mediashow_address1
add index FK5FD5BCE8801495D (empid),
add constraint FK5FD5BCE8801495D
foreign key (empid)
references mediashow_user1 (empid)
If you want to make this work for Unidirection one-to-one relation ship then you should handle the cascade operations yourself. Basically you should do the following
1)Remove the foreign key strategy (Just use @Id and @column annotations for empId in AddressVO with out any @GeneratedValue).
2)Remove the cascade options for AddressVo in your UserVO (as this will trigger similar operations on AddressVO and the id is still not known)
3)Set the empId for AddressVo before saving this address. You should use the id that you obtain when you save userVo.
Long id= (Long)session.save(user);
address.setEmpid(id);
session.save(address)
basically you should handle the save/update/delete operations for addresss too.
Hope this explanation helps :)
Upvotes: 5