I am Upgrading Spring Application from java 8 to Java 11 - java

I am upgrading a project from Java-8 to Java-11 which is using eclipselink 2.7.0 and while running application i am getting below mentioned error.
Exception Description: Problem compiling [ select org from Organization org ]. The abstract schema type '' is unknown.
Here is my Organization class
#Entity(name="Organization")
#NamedQuery(name="getOrganizationByTenant",query="select o from Organization o where o.organizationName=:orgName and o.tenantId=:tenantId")
#Table(name = "Organization", schema = "xyz")
public class Organization {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long organizationId;
#Size(min = 1, max = 300)
#SpecialCharValidator
private String organizationName;
#Size(min = 0, max = 4000)
#SpecialCharValidator
private String organizationFullName;
#Size(min = 0, max = 4000)
#SpecialCharValidator
private String remarks;
#NotNull
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="organizationType")
private Code organizationType;
#NotNull
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="organizationSubType")
private Code organizationSubType;
private Long parentOrganizationId;
#Size(min = 0, max = 1000)
private String organizationURL;
#NotNull private Long tenantId;
private Integer createdBy;
private Date createdOn;
private Integer updatedBy;
private Date updatedOn;
private boolean isDeleted;
private Boolean isShared;
}
```
Here is my function code that is fetching data :
return filters.getList(em, Organization.class," select org from Organization org ", options,SORT_COLUMNS);

Related

Entity fetched using findById has all fields set to NULL

Entity fetched using Hibernate has all fields set to NULL. How can I avoid this?
This is my Jpa Repository.
#Repository
public interface PolicyRepository extends JpaRepository<Entity, Long>{
Entity findByEntSeqNo(#Param("entSeqNo") long entSeqNo);
}
When debugged I can see that fetched data are inside a field name $$_hibernate_interceptor
This is my entity class
#Entity
#Table(name = "ENTITY_TABLE")
#Lazy(value = false)
public class Entity extends AuditModel {
#Id
#Column(name = "ENT_SEQ_NO")
#GeneratedValue(generator="entitySeq")
#SequenceGenerator(name="entitySeq",sequenceName="\"ENT_SEQ_NO_seq\"", allocationSize=1)
private long entSeqNo;
#Column(name = "ENT_CUSTOMER_CODE")
#NotEmpty(message = "Customer Code is Required.")
private String entCustomerCode;
#Column(name = "ENT_CLAS_CODE")
#NotEmpty(message = "Class Code is Required.")
private String polcClasCode;
#Column(name = "ENT_PROD_CODE")
#NotEmpty(message = "Product Code is Required.")
private String entProdCode;
#Column(name = "ENT_BRANCH_CODE")
#NotEmpty(message = "Branch Code is Required.")
private String entBranchCode;
#Column(name = "ENT_YYY_NO")
#NotEmpty(message = "Yyy Number is Required.")
private String entYyylNo;
#Column(name = "ENT_XX_NO")
private String entXxNo;
#Column(name = "ENT_XXX_NO")
private String entXxxNo;
#Column(name = "ENT_COMMENCEMENT_DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date entCommencementDate;
#Version
#NotNull(message = "Version is Required.")
#Column(name = "VERSION")
private int version;
#Column(name = "ENT_EXPIRY_DATE")
#NotNull(message = "Entity Expiry Date is Required.")
#Temporal(TemporalType.TIMESTAMP)
private Date entExpiryDate;
#Column(name = "ENT_DELIVERY_MODE")
private String entDeliveryMode;
#Column(name = "ENT_COLLECTED_BY")
private String entCollectedBy;
#Column(name = "ENT_COLLECTED_USER_NIC")
private String entCollectedUserNic;
#Column(name = "ENT_COLLECTED_USER_MOBILE")
private String entCollectedUserMobile;
#Column(name = "ENT_COLLECTED_DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date entCollectedDate;
#Column(name = "ENT_POSTED_DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date entPostedDate;
#Column(name = "ENT_POSTED_REF_NO")
private String entPostedRefNo;
#Column(name = "ENT_LANG_CODE")
private String entLangCode;
#Column(name = "ENT_PP1_ID", insertable = false, updatable = false)
private Long entPp1Id;
#Column(name = "ENT_STATUS")
private Short entStatus;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "ENT_PP1_ID", referencedColumnName = "ID")
private Pp1 entPp1;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "ENT_EPP1_ID", referencedColumnName = "ID")
private Epp1 entEpp1;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx")
private Collection<TaskLog> taskLogColletion;
}
I'm asking this here since I couldn't find the exact cause for this behavior. All the Jpa operations are working fine and this happens only when I try to pick the details from the database. I also tried getOne method and the same problem occurs.
You do not need the method : Entity findByEntSeqNo(#Param("entSeqNo") long entSeqNo); in your jpa interface because entSeqNo is an id of your entity.
So whene you want to get one Entity by id you can just call policyRepository.getOne(the value of entSeqNo) provided by JpaRepository
Or you can use policyRepository.findById(the value of entSeqNo) provided by CrudRepository whitch is basically a superinterface of JpaRepository
Ps: Do no overwrite these methods in you interface.

Need to understand the java 8 behavior for creating objects and updating reference

I am failed to understand the following problem.
I have one DTO file as follows.ClientRegistrationDTO.java
public class ClientRegistrationDTO {
private Long clientId;
private String clientCode;
private String clientName;
private String url;
private String logo;
private Long languageId;
private String timeZone;
//contact details
private Set<Address> addresses;
private Set<ContactDetails> contactDetails;
public ClientRegistrationDTO(){}
public ClientRegistrationDTO(Set<Address> addressSet,Set<ContactDetails> contactDetails){
this.addresses = addressSet;
this.contactDetails = contactDetails;
}
}
So I have a method registerClient which accept this DTO file to operate over the save client as well as a user. As follows
public ClientRagistrationResponce registerClient(
ClientRegistrationDTO clientRegistrationDTO) {
ClientRagistrationResponce clientInfo = null;
if (clientRegistrationDTO != null) {
clientInfo = new ClientRagistrationResponce(); // creating responce variable
//setting another ragisterDTO file with default value
ClientRegistrationDTO clientRegistrationDTO2 = new
Line no 9 ClientRegistrationDTO(clientRegistrationDTO.getAddresses(),clientRegistrationDTO.getContactDetails());
// creating addresses Set from clientRegistrationDTO to insert
// against user.
Line no 15 Set<Address> clientAddress = new HashSet<>(clientRegistrationDTO.getAddresses());
Line no 16 Set<ContactDetails> clientContactDetails = new HashSet<>(clientRegistrationDTO.getContactDetails());
Line no 18 Set<Address> userAddress = new HashSet<>(clientRegistrationDTO2.getAddresses());
Line no 19 Set<ContactDetails> userContactDetails = new HashSet<>(clientRegistrationDTO2.getContactDetails());
// Save the client
Client client = saveClient(clientRegistrationDTO);
// Save the contact info
ContactInfo clientContactInfo = saveContactInfo(
client.getClientId(), RDHCoreConstants.CONTACT_TYPE_CLIENT);
// Save client addresses
Line no 29 Set<Address> clientAddressSet = saveClientAddresses(
clientContactInfo.getContactInfoId(), clientAddress);
// Save Client contact details
Line no 33 Set<ContactDetails> clientContactDetailsSet = saveClientContactDetails(
clientContactInfo.getContactInfoId(), clientContactDetails);
// save user
User user = saveUser(clientRegistrationDTO);
// Save User contact info
ContactInfo userContactInfo = saveContactInfo(user.getUserId(),
RDHCoreConstants.CONTACT_TYPE_USER);
// Save User addresses
saveUserAddresses(userContactInfo.getContactInfoId(), userAddress);
// Save User contact details
saveUserContactDetails(userContactInfo.getContactInfoId(),
userContactDetails);
saveClientUser(client.getClientId(), user.getUserId());
// setting the return DTO
clientInfo.setClientId(client.getClientId());
clientInfo.setAddresses(clientAddressSet);
clientInfo.setContactDetails(clientContactDetailsSet);
}
return clientInfo;
}
Firstly I created another Object with a different name of the same type to set address & contact details are safe with updation. #Line no 9.
So now whenever the client Address & ContactDetails saved # line no 29 & 33. it updates the address in ClientRagistrationDTO.java file and all the reference which I passed to create another set of Address and contactDetails. # Line no 9.
I'm confused, why it's updating all its reference, even though I never updated the same.
Please guide me step by steps.
Note: I used Spring Data JPA with following relation ContactInfo table has a contactInfoId as primary_key. whihc is foreign_key in Address as well as ContactDetails.
Follwing is the entity of the tables.ContactInfo
#Entity
#Table(name = "contactinfo", schema = "test")
public #Data class ContactInfo {
#Id
#Column(name = "CONTACTINFOID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long contactInfoId;
#Column(name="CLIENTUSERID")
private Long clientUserId;
#Column(name = "CONTACTTYPE")
#NotNull
#Size(min = 1, max = 10)
private String contactType;
}
Follwing is the Address
#Entity
#Table(name = "address", schema = "test")
public class Address {
#Id
#Column(name = "ADDRESSID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long addressId;
#Column(name = "ADDRESS1")
#Size(min = 1, max = 50)
private String address1;
#Column(name = "ADDRESS2")
#Size(min = 1, max = 50)
private String address2;
#Column(name = "CITY")
#Size(min = 1, max = 50)
private String city;
#Column(name = "ZIP")
#Size(min = 1, max = 15)
private String zip;
#Column(name = "STATE")
#Size(min = 1, max = 50)
private String state;
#Column(name = "COUNTRY")
#Size(min = 1, max = 50)
private String country;
#Column(name = "ISPRIMARY")
#NotNull
#Size(min = 1, max = 1)
private String isPrimary;
#Column(name = "CONTACTINFOID")
private Long contactInfoId;
}
Follwing is the ContactDetails.
#Entity
#Table(name = "contactdetails", schema = "test")
public class ContactDetails {
#Id
#Column(name = "CONTACTDETAILSID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long contactId;
#Column(name = "CONTACTTYPE")
#NotNull
#Size(min = 1, max = 20)
private String contactType;
#Column(name = "CONTACTDETAIL")
#NotNull
#Size(min = 1, max = 20)
private String contactDetail;
#Column(name = "EXTENSION")
private String extension;
#Column(name = "ISPRIMARY")
#NotNull
#Size(min = 1, max = 1)
private String isPrimary;
#Column(name = "CONTACTINFOID")
private Long contactInfoId;
}
Hope enough information is provided to solve this issue.

Crud Repository, date comparison

I have the following sql query:
select * from wash_history w where w.wash_id in
(select wash.id from wash where wash.car_wash_id = 17)
and w.time between '2017-07-13' and '2017-07-22'
And I want to create this query inside interface that extends CrudRepository. The method is
Page<WashHistory> findWashHistoryByTimeBetweenOrderByTimeDesc(Date dateFrom,
Date dateTo,
Pageable pageable);
But this method always returns an empty list, I think is it due to Java date and SQL TimeStamp? If you want some more details I can add them to question. My class:
public class WashHistory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
// #Max(value=?) #Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
#Column(name = "wash_price")
private Double washPrice;
#Size(max = 2147483647)
#Column(name = "car_wash_name")
private String carWashName;
#Basic(optional = false)
#NotNull
#Column(name = "time")
#Temporal(TemporalType.TIMESTAMP)
private Date time;
#Size(max = 2147483647)
#Column(name = "status")
private String status;
#Column(name = "bonuses")
private Integer bonuses=0;
#JoinColumn(name = "wash_id", referencedColumnName = "id")
#ManyToOne(fetch = FetchType.LAZY)
private Wash washId;}
ANd wash class
public class Wash implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Size(max = 2147483647)
#Column(name = "status")
private String status;
#Column(name = "using_bonuses")
private Boolean usingBonuses=false;
#Basic(optional = false)
#NotNull
#Column(name = "last_status_time")
#Temporal(TemporalType.TIMESTAMP)
private Date lastStatusTime;
#OneToMany(mappedBy = "washId", fetch = FetchType.LAZY)
private Set<WashHistory> washHistorySet;
#OneToOne(mappedBy = "washId", fetch = FetchType.LAZY)
private WashComment washCommentSet;
#JoinColumn(name = "car_wash_id", referencedColumnName = "id")
#ManyToOne(fetch = FetchType.LAZY)
private CarWash carWashId;}
My pageble
public class LimitAndOffsetPageable extends PageRequest {
private int page;
private int size;
public LimitAndOffsetPageable(int page, int size){
super(page,size);
this.page=page;
this.size=size;
}
#Override
public int getOffset(){
return this.page;
}
}
I pass to findWashHistoryByTimeBetweenOrderByTimeDesc(new LimitAndOffsetPageable (0,100)) (offset = 0 , limit = 100)
Your problem is caused by using bad naming conventions: Your entities should look like following: (removed redundant lines - if you want to add constraints like not null, add them in #Column)
#Entity
public class WashHistory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "wash_price")
private Double washPrice;
#Column(name = "car_wash_name")
private String carWashName;
#Column(name = "time")
#Temporal(TemporalType.TIMESTAMP)
private Date time;
private String status;
private Integer bonuses=0;
#JoinColumn(name = "wash_id", referencedColumnName = "id")
#ManyToOne(fetch = FetchType.LAZY)
private Wash wash;
}
Now, the method could be:
Page<WashHistory> findAllByWashIdIdAndTimeBetween(Integer id, Date start, Date end, Pageable pageable)
Sort property should be put into pageable object.

Spring Architecture circular references and stackoverflows

I have a question about how to avoid circular references and stackoverflows.
I have a User object and another News Object (with a User variable). I need a Comments object (that already has a News variable), but I also need that it has a reference to the User that has created the Comment.
If I create a User variable inside my Comment object I will have circular references and stackoverflows, so I think that I should only incluide a variable like userid in my Comment object.
So it could be that I'm right in my thinking or that I'm doing something wrong to get the stackoverflow errors. What would you do and why? If you can help, that will be great. Thanks.
This is the User...
#Entity
#Table(name = "users")
#PasswordMatch(message = "{register.repeatpassword.mismatch}")
public class SiteUser {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Column(name = "email", unique = true)
#Email(message = "{register.email.invalid}")
#NotBlank(message = "{register.email.invalid}")
private String email;
#Transient
#Size(min = 5, max = 15, message = "{register.password.size}")
private String plainPassword;
#Column(name = "password", length = 60)
private String password;
#Column(name = "enabled")
private Boolean enabled = false;
#NotNull
#Column(name = "firstname", length = 20)
#Size(min = 2, max = 20, message = "{register.firstname.size}")
private String firstname;
#NotNull
#Column(name = "surname", length = 25)
#Size(min = 2, max = 25, message = "{register.surname.size}")
private String surname;
#Transient
private String repeatPassword;
#Column(name = "role", length = 20)
private String role;
public SiteUser() {
}
Here comes the StatusUpdate(you can call it piece of news or article). It has a site user that is the one who has created that article.
#Entity
#Table(name = "status_update")
public class StatusUpdate {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Size(min=5, max=255, message="{addstatus.title.size}")
#Column(name = "title")
private String title;
#Size(min=5, max=5000, message="{addstatus.text.size}")
#Column(name = "text")
private String text;
#Column(name = "added")
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern="yyyy/MM/dd hh:mm:ss")
private Date added;
#OneToOne(targetEntity = SiteUser.class)
#JoinColumn(name="user_id")
private SiteUser siteUser;
#PrePersist
protected void onCreate() {
if (added == null) {
added = new Date();
}
}
public StatusUpdate() {
}
And the Comment which can be done by any registered user, right? As you will notice the Comment has no User object to avoid circular references. And that is the question. How can avoid circular references if Autowired a User
#Entity
#Table(name = "comments")
public class Comment {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#ManyToOne
#JoinColumn(name = "statusupdateid")
private StatusUpdate statusUpdate;
#Column(name = "commenttext")
private String commenttext;
#Column(name = "commentdate")
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern = "yyyy/MM/dd hh:mm:ss")
private Date commentdate;
#Column(name = "userid")
private Long userid;
public Comment() {
}

Eclipselink ValidationException

I am trying to adapt my data model to use a BaseEntity base-class. The following code represents the general idea:
#MappedSuperclass
public abstract class BaseEntity implements HasAuditInfo {
#Id
#GeneratedValue
private Long id;
#Column(unique = true, nullable = false)
private String uuid;
private Long createdById;
#Temporal(value = TemporalType.TIMESTAMP)
#Column(nullable = false)
private Date createdOn;
private Long changedById;
#Temporal(value = TemporalType.TIMESTAMP)
#Column(nullable = false)
private Date changedOn;
#Column(nullable = false)
private Long changedOnValue;
private Boolean active;
private Long deactivatedById;
#Temporal(value = TemporalType.TIMESTAMP)
private Date deactivatedOn;
#NotNull
#DecimalMin("0")
private Integer version = 0;
private Long domainId;
[... Getters/Setters etc ...]
}
The following is an example of a derived entity:
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Address extends BaseEntity implements Serializable, Comparable<Address> {
private static final long serialVersionUID = 6301090657382674578L;
// Address Fields
#NotBlank(message = "Address Line 1 is a mandatory field.")
private String addressLine1;
private String addressLine2;
private String country;
#NotBlank(message = "Region is a mandatory field.")
private String region;
#NotBlank(message = "City is a mandatory field.")
private String city;
#NotBlank(message = "Zipcode is a mandatory field.")
private String zipcode;
[... Getters/Setters etc ...]
}
If I'm understanding the JPA documentation correctly, this should be perfectly valid, yet I get the following error from EclipseLink when deploying my code:
Entity class [class
com.x.y.z.Address] has no primary key specified.
It should define either an #Id, #EmbeddedId or an #IdClass. If you
have defined PK using any of these annotations then make sure that you
do not have mixed access-type (both fields and properties annotated)
in your entity class hierarchy.
I've tried a few things to work around this:
Upgrading to EclipseLink 2.3 (I'm currently using 2.2)
Making BaseEntity non-abstract
Moving the #Id annotation and field directly into Address
Annotating the getId() method instead of field both in BaseEntity and in Address.
None of these approaches have had any effect, short of migrating my code to Hibernate (or some other, better, JPA implementation), is there anything I can do?
The solution is to explicitly name each column in BaseEntity, as follows:
#MappedSuperclass
public abstract class BaseEntity {
#Id
#GeneratedValue
#Column(name = "id")
#SearchableId
protected Long id;
#Column(name = "uuid", unique = true, nullable = false)
protected String uuid;
#Column(name = "createdById")
protected Long createdById;
#Temporal(value = TemporalType.TIMESTAMP)
#Column(name = "createdOn", nullable = false)
protected Date createdOn;
#Column(name = "changedById")
protected Long changedById;
#Temporal(value = TemporalType.TIMESTAMP)
#Column(name = "changedOn", nullable = false)
protected Date changedOn;
#Column(name = "changedOnValue", nullable = false)
protected Long changedOnValue;
#Column(name = "active")
protected Boolean active;
#Column(name = "deactivatedById")
protected Long deactivatedById;
#Temporal(value = TemporalType.TIMESTAMP)
#Column(name = "deactivatedOn")
protected Date deactivatedOn;
#Version
#Column(name = "version")
protected Integer version = 0;
#Column(name = "domainId")
protected Long domainId;
You should not get this error. And definitely not if you move the #Id into the Address.
Are you sure you recompiled/deployed your code after making the changes?
If you remove the TABLE_PER_CLASS inheritance does it work? (does Address have subclasses?)

Categories