GWT JPA - The response could not be deserialized - java

I use GWT and JPA for persistence. I have created a domain JPA enchanted classes, DAO's and RPC for communication between them. Everything works fine, through RPC the client sends the object to server but could not get response. Server cannot deserialize in a compatible way with the client side. So i cannot use the server callBack back to the client. The exception message is this:
The response could not be
deserialized,
com.google.gwt.user.client.rpc.SerializationException
Here's a sample code of one of my classes:
#Entity
#Table(name="course")
public class Course implements Serializable {
private static final long serialVersionUID = 1L;
private int courseId;
private String name;
private List<Group> groups;
private List<Module> modules;
public Course() {
}
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(unique=true, nullable=false)
public int getCourseId() {
return this.courseId;
}
public void setCourseId(int courseId) {
this.courseId = courseId;
}
#Column(nullable=false, length=100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//bi-directional many-to-one association to Group
#OneToMany(mappedBy="course", fetch=FetchType.LAZY)
public List<Group> getGroups() {
return this.groups;
}
public void setGroups(List<Group> groups) {
this.groups = groups;
}
//bi-directional many-to-one association to Module
#OneToMany(mappedBy="course", fetch=FetchType.LAZY)
public List<Module> getModules() {
return this.modules;
}
public void setModules(List<Module> modules) {
this.modules = modules;
}
}
If i remove the relationships it work's fine. This is done because collections like lists, set's e.t.c are converted into hibernate objects that cannot be handled by GWT client side.

Well the problem is that my class has #OneToMany association to another class. If i remove the association it work's fine. But it's impossible to that, since I use a normalized relational database

If you're using GWT-RPC, make sure that all of the classes you're trying to serialize have a public default (no-argument) constructor and implement Serializable. If you have embedded classes, they must also have a no-arg constructor.

Once , I have prepared gwt-jpa sample for this question. It is just serialization of JPA entity.. It might give you a clue about what is wrong in your case..

I used Gilead and it fixed the issue.
Please check the corresponding post: GWT with JPA

got it working...after a redeploy of war again...strange..cant point to one specific thing (as i did clear browser cache/eclipse classes output/restart eclipse)
Apparently workaround seems to be try redeploying webapp whenever this issue occurs..

Related

Hibernate yes_no does not work when in entity from a dependency

I'm trying to create a common hibernate entities package to re-use in multiple microservices of my project.
My DB stores booleans in a form of Y/N, so I need to use #Type(type="yes_no") on every boolean property.
For instance: (just an example, not a real entity)
#Entity
#Table(name="USERS")
#Setter
class User {
private Long id;
private String name;
private boolean isAdmin;
#Id
#Column(name="ID")
public Long getId() {
return id;
}
#Column(name="NAME")
public String getName() {
return name;
}
#Column(name="IS_ADMIN")
#Type(type="yes_no")
public boolean getIsAdmin() {
return isAdmin;
}
}
When I try to execute any query, for instance to get all admins, using spring jpa:
List<User> findByIsAdminTrue();
It does not convert true to Y and throws an error "TRUE": invalid identifier.
The weird part is, it happens only when I import the User entity with a maven dependency. When it exists within the same project it works fine.
I have an #EntityScan annotation on the spring boot main class, and I've tried everything I could think of.
Does anyone know why could this happen?

Saving entity with Spring JPA Repository resets enum ttype value

I have an TimelineEntity entity, that uses HoTimelineType enum with custom integer value. That custom integer value is stored in the database. Implemented via Using #PostLoad and #PrePersist Annotations
Sprint JPA Repository is used to save and get entities.
Here is the issue:
#Entity
#Table(name = TABLE_NAME)
#IdClass(TimelineKey.class)
public class TimelineEntity {
public interface Persistence {
String TABLE_NAME = "timelines";
}
#Id
#Column(name = "node_id")
private Long nodeId;
#Id
#Column(name = "timeline_id")
private Long timelineId;
#Column(name = "ho_timeline_type")
private Integer hoTimelineTypeValue;
#Transient
private HoTimelineType hoTimelineType;
public Long getNodeId() {
return nodeId;
}
public void setNodeId(Long nodeId) {
this.nodeId = nodeId;
}
public Long getTimelineId() {
return timelineId;
}
public void setTimelineId(Long timelineId) {
this.timelineId = timelineId;
}
public HoTimelineType getHoTimelineType() {
return hoTimelineType;
}
public void setHoTimelineType(HoTimelineType hoTimelineType) {
this.hoTimelineType = hoTimelineType;
}
public Integer getHoTimelineTypeValue() {
return hoTimelineTypeValue;
}
public void setHoTimelineTypeValue(Integer hoTimelineTypeValue) {
this.hoTimelineTypeValue = hoTimelineTypeValue;
}
#PostLoad
private void postLoad() {
this.hoTimelineType = HoTimelineType.of(hoTimelineTypeValue);
}
#PrePersist
private void prePersist() {
this.hoTimelineTypeValue = hoTimelineType.getValue();
}
}
#Eager
public interface TimelineEntityRepository extends JpaRepository<TimelineEntity, TimelineKey> {
List<TimelineEntity> findByNodeId(Long nodeId);
}
#Autowired
private TimelineEntityRepository timelineEntityRepository;
...
TimelineEntity newTE = new TimelineEntity();
newTE.setNodeId(10L);
newTE.setTimelineId(22L);
newTE.setHoTimelineType(HoTimelineType.TYPE_1);
newTE = timelineEntityRepository.save(newTE);
When the newTE entity is saved, prePersist is invoked, and inside this method, the hoTimelineType is null and I get NPE. nodeId and timelineId are not nulls. If I stay with a debugger on the last line, outside of prePersist, I see that hoTimelineType has the value, I set before.
When I load entities, inserted with test data, everything works fine and both hoTimelineType and hoTimelineTypeValue have not nullable values.
I skipped the code of TimelineKey and HoTimelineType to simplify the example. Can add it, if needed.
What could reset hoTimelineType? What do I miss?
It seems there is no way to control the saving behaviour of spring jpa repository proxy.
Possible solutions for issue:
Via javax.persistence.Converter. It is pretty clear, the structe of an entity is simple. Can confirm it works fine with Spring Jpa Repository generation.
Explicitely set hoTimelineTypeValue before you save an entity. Error-prone solution. Everytime you save an entity you must think about the difference between the hoTimelineTypeValue and hoTimelineType.
You could enrich setters and getters of the entity class, to explicitely control the consistency between the fields. It makes implementation of entity classes not so obvious. You get more compicated solution for nothing. As a result error-prone solution. Do not recommend it as well.
Cause of disadvantages of #2 and #3 I do not provide examples. It makes no sense.
Example of the solution #1 can be found here: Using JPA 2.1 #Converter Annotation

JPA Entity issue with ID

I'm building one application using JPA, I want to have a parent entity called "BaseEntity" with the attribute ID and then the rest of the entities extending this entity and then having their own attributes. The field id in the parent class is protected. However when I start the server I'm getting the following error:
Caused by: org.hibernate.AnnotationException: No identifier specified for entity: com.fgonzalez.domainmodel.User
Of course if I place the id field in the class User, it is working fine but this is not what I want. The weird thing is if I use xml files for the hibernate mappings instead of JPA, it works fine, but not with JPA. Any idea where can be the problem? Attached the code:
Base Entity:
public class BaseEntity implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name="id")
protected Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
And User entity:
#Entity
#Table(name="users")
public class User extends BaseEntity{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
*
*/
#Column(name="EMAIL",nullable=false,length=50,insertable=true,updatable=true)
private String email;
#Column(name="PASSWORD",nullable=false,length=50,insertable=true,updatable=true)
private String password;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email=email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Thank you in advance!!
You can't do that this way: BaseEntity isn't an #Entity, so #Id shouldn't even be processed.
If Hibernate does process it while using xml, that's probably a non-portable specificity.
You could implement some entity hierarchy, but I wouldn't do it in this case. You can only extend once, and this doesn't look like a real hierarchy: only one root, shared by every class?
You can find more information on entity inheritance here: http://docs.oracle.com/javaee/6/tutorial/doc/bnbqn.html
You could use compositions instead of inheritance. In this case, just annotate your User class (which wouldn't be an #Entity) with #Embeddable, and have a field annotated with #EmbeddedId on the using class.
Still, I wouldn't do that: it seems more DRY, but it has no more benefits that replacing String everywhere with something else just to not repeat yourself (which you would then do anyway).
I would just have an #Id Long id; field in every entity, freeing them from hierarchy hell. It looks more boilerplate, but will be much easier in the long term, with no obvious disadvantage.
If you are going implement inheritance in JPA, you are not suppose to do like in java. JPA got its own implementation strategies. Have a look here and choose the one that best suits your need

spring data jpa composite key duplicate key record insertion resulting in update

I have one entity having composite key and I am trying to persist it by using spring data jpa repository to mysql databse as given below:
#Embeddable
public class MobileVerificationKey implements Serializable{
private static final long serialVersionUID = 1L;
#Column(name="CUSTOMERID")
private Long customerId;
#Column(name="CUSTOMERTYPE")
private Integer customerType;
#Column(name="MOBILE")
private Long mobile;
#Embeddable
public class MobileVerificationKey implements Serializable{
private static final long serialVersionUID = 1L;
#Column(name="CUSTOMERID")
private Long customerId;
#Column(name="CUSTOMERTYPE")
private Integer customerType;
#Column(name="MOBILE")
private Long mobile;
//getter and setters
}
And Entity as
#Entity
#Table(name="mobileverificationdetails")
public class MobileVerificationDetails {
#EmbeddedId
private MobileVerificationKey key;
#Column(name="MOBILETYPE")
private String mobileType;
#Column(name="MOBILEPIN")
private Integer mobilePin;
//getters and setters
}
My spring data jpa repository look like this:
public interface MobileVerificationDetailsRepository extends
CrudRepository<MobileVerificationDetails, MobileVerificationKey> {
#Override
MobileVerificationDetails save(MobileVerificationDetails mobileVerificationDetails);
#Override
MobileVerificationDetails findOne(MobileVerificationKey id);
}
Now if I am trying to add duplicate record with same key for original record and different values for other fields .when i try to insert second record it results in update of existing record with new values instead of throwing exception for violating primary key constraint...can any one please explain me this behavior.
The easiest (and least invasive) way to work around this is probably by making sure the id only gets set right before the persist. This can be achieved in a #PrePersist callback:
abstract class MobileVerificationDetails {
#EmbeddedId
private MobileVerificationKey id;
#PrePersist
void initIdentifier() {
if (id == null) {
this.id = … // Create ID instance here.
}
}
}
Alternatively to that you can enforce persist(…) being used by implementing Persistable and implementing isNew() accordingly. Make sure this method returns true on first insert. We usually see people holding a transient boolean flag that is updated in an #PostPersist/#PostLoad annotated method.
abstract class AbstractEntity<ID extends Serializable> implements Persistable<ID> {
private #Transient boolean isNew = true;
#Override
public boolean isNew() {
return isNew;
}
#PostPersist
#PostLoad
void markNotNew() {
this.isNew = false;
}
}
Spring Data Jpa Repository functionality is implemented via the SimpleJpaRepository class containing following save(..) method:
#Transactional
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
Thus the Spring Jpa Data Repository save(...) method merges an already existing entity.
Opposed to that the naked EntityManager#persist() throws an exception if invoked with already existing entity.
The problem might be solved by adding custom behavior to Spring Data Repository/ies. The custom behavior might be added using one of the approaches as described in 1.3.1 Adding custom behavior to single repositories with example here or in 1.3.2 Adding custom behavior to all repositories with example here. In both cases the custom behavior would include a new persist() method delegating to EntityManager#persist(). Note that in approach 1.3.2. you already have a EntityManager instance, in the approach 1.3.1 you are able to inject EntityManager instance using the #PersistenceContext.
Opposed to my comment I would recommend adding new method to the repository and not overwriting the existing save(...).

hibernate jpa entitymanager commit not writing objects to the database

I'm using hibernate JPA (without Spring) and it's working well, but I have come across a problem which has stumped me for the last 3 days.
I have written some generic DAO classes and am using them to persist my objects. They all work fine, except for one class of object which is not being persisted. No exceptions are thrown. I've tried debugging inside the hibernate code and found that the reason the entity is not being persisted is that in the org.hibernate.event.def.DefaultFlushListener onFlush() method, source.getPersistenceContext().getEntityEntries().size() == 0 so no flushing is performed. But I can't work out why that would be the case.
The classes in question look like this:
#Entity
#Table(name="er_batch_runs")
public class BatchRun implements Serializable, Comparable<BatchRun>, BatchBean {
private Long runId;
private String hostname;
.... more field here
#Override
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="runseq")
#SequenceGenerator(name="runseq", sequenceName="er_batch_runs_seq", allocationSize=1 /*, initialValue = 10*/)
#Column(name="batch_run_id")
public Long getId() {
return runId;
}
public void setId(long runId) {
this.runId = runId;
}
#Column(name="hostname")
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
pretty straightforward hibernate JPA stuff.
Here's another class:
#Entity
#Table(name="er_batch_txns")
public class BatchTxn implements Serializable, Comparable<BatchTxn>, BatchBean {
private long id;
.......... more fields
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="batchtxnseq")
#SequenceGenerator(name="batchtxnseq", sequenceName="ER_BATCH_TXNS_SEQ", allocationSize=1/*00, initialValue = 10*/)
#Override
#Id
#Column(name="BATCH_TXN_ID")
public Long getId() {
return id;
}
the BatchBean interface is what allows me to use generic DAOs like this:
public Long create(BatchBean newInstance) {
getOpenEntityManager().persist(newInstance);
logger.debug("hopefully created {} with id {}",newInstance.getTypeName(),newInstance.getId());
return newInstance.getId();
}
Transactions are being handled manually. I've set the flush type to COMMIT (ie flush on commit) and when I've completed the persist, I do a commit. After the persist, then BatchTxn object has been assigned a primary key from the sequence. When I debug hibernate I can see that getPersistenceContext().getEntityEntries() returns an empty Map.
so the question is why the BatchTxn is not being persisted by the commit, when the BatchRuns, and 5 other classes which implement BatchBean, are?
I'm using hibernate 3.6.0 Final
The only thing I saw that is suspected in your code is this in the BatchTxn class:
private long id;
This will be set automatically to zero. Maybe you should use Long (with a capital letter)?

Categories