How to call service based classes from entity class in spring boot - java

This is an entity class of my Multi-tenancy project
#Entity
public class Customer {
private String uniqueCustomerId;
private String firstName;
private String lastName;
#Convert(converter = CryptoConverter.class)
private String mobile;
private String mobileShavalue;
}
In my CryptoConverter.java I am checking whether I have to encrypt this attribute or not, from the configuration and encryption logic written in CryptoConverter.java. Also, if the configuration tells that i have to encrypt the mobile attribute then in that case i have to also store the sha value(sha1 or sha2 from config) for attribute mobileShavalue.
One thing came in my mind to achieve this, is through using #PrePersist in my entity class and again getting configuration from PrePersist method to validate whether I have to store mobile sha value or not and writing shavalue logic there.
But when I do this I am getting below error
#Autowired
EncryptionConfigService encryptionConfigService;
#PrePersist
private void doSomeCode(){
encryptionConfigService.callNewMethod();
}
Caused by: org.hibernate.MappingException: Could not determine type for: com.loylty.tms.service.EncryptionConfigService, at table: Customer, for columns: [org.hibernate.mapping.Column(encryption_config_service)]

Annotate the autowired service with #Transient to make the ORM ignore it during serialization
#Transient
#Autowired
EncryptionConfigService encryptionConfigService;
#PrePersist
private void doSomeCode(){
encryptionConfigService.callNewMethod();
}

Related

Can we use Composite Primary Key Mapping in spring data elastic search

I have an entity 'Product' and I want the primary key in ES to be used as a combination of 'id' and 'name' attributes. How can we do that using spring data elastic search.
public class Product {
#Id
private String id;
#Id
private String name;
#Field(type = FieldType.Keyword)
private Category category;
#Field(type = FieldType.Long)
private double price;
#Field(type = FieldType.Object)
private List<ValidAge> age;
public enum Category {
CLOTHES,
ELECTRONICS,
GAMES;
}
}
One way to achieve this would be the following:
first rename your id property, I changed it to documentId here. This is necessary, because in Spring Data
Elasticsearch an id-property can be either annotated with #Id or it can be namend id. As there can only be one
id-property we need to get this out of the way. It can have the name id in Elasticsearch, set by the #Field
annotation, but the Java property must be changed.
second, add a method annotated with #Id and #AccessType(AccessType.Type.PROPERTY) which returns the value you
want to use in Elasticsearch.
third, you need to provide noop-setter for this property. This is necessary because Spring Data Elasticsearchsoe
not check the id property to be read only when populating an entity after save or when reading from the index.
This is a bug in Spring Data Elasticsearch, I'll create an issue for that
So that comes up with an entity like this:
#Document(indexName = "composite-entity")
public class CompositeEntity {
#Field(name="id", type = FieldType.Keyword)
private String documentId;
#Field(type = FieldType.Keyword)
private String name;
#Field(type = FieldType.Text)
private String text;
#Id
#AccessType(AccessType.Type.PROPERTY)
public String getElasticsearchId() {
return documentId + '-' + name;
}
public void setElasticsearchId(String ignored) {
}
// other getter and setter
}
The repository definition would be straight forward:
public interface CompositeRepository extends ElasticsearchRepository<CompositeEntity,
String> {
}
Remember that for every method that needs an Elasticsearch Id, you'll need to create like it's done in the entity
class.
I am not sure about spring data elasticsearch but spring jpa provides the facility of defining composite primary key by using #IdClass where we can define a separate class(let us say class A) in which we can define all the fields which we want to be a part of composite key Then we can use #IdClass(A.class) in entity class and use #Id annotation on all the fields which should be the part of the composite key
you can refer to this article, although I am not sure whether the same concept will be applicable for spring data es - https://www.baeldung.com/jpa-composite-primary-keys

in Java when Using Hibernate for CRUD how could we access a Header value from the initial Resteasy request [duplicate]

This question already has an answer here:
When using Quarkus rest data Panache how to access username from request header in #PrePersist
(1 answer)
Closed 2 years ago.
please I need help from a Java expert.
I would like to store the user how modified the record in a field of a database table using Hibernate’s #PreUpdate.
The user name is set in header field x-remote-user by the reverse proxy. I can access it as shown below
#GET
#Path("/getuser")
public String get( #HeaderParam("x-remote-user") String userName) {
return userName;
}
Is there a way to inject #HeaderParam in my JPA entity bean? Should I lookup reflections?
This didn’t work:
#Entity
#Table(name = "t_companies")
public class TBusiness extends PanacheEntityBase {
#Column(name = "company_name", nullable = true)
public String companyName;
#Column(name = "updated_by", nullable = true)
public String updatedBy;
#PreUpdate
public void preUpdate(#HeaderParam("x-remote-user") String userName) {
updatedBy = userName;
}
}
Let me reformulate my question
I am using Panache data REST CRUD generation
Is there a way to have access to the header value that holds the username from a #RequestScoped class
Then use this value in the JPA entities on #PreUpdate?
got this to work by adding undertow dependency :
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-undertow</artifactId>
</dependency>
then in an EntityListener class created below PrePersist method:
#RequestScoped
// #Path("api/v1/Header")
public class AuditingEntityListener {
private static final Logger LOG = Logger.getLogger(AuditingEntityListener.class);
// Inject the bean so that Quarkus does not remove it at build time (IMPORTANT)
#Inject
HttpServletRequest requestNotUsed;
#PrePersist
void onPrePersist(TBusiness myEntity) {
HttpServletRequest HSR = CDI.current().select(HttpServletRequest.class).get();
LOG.info("HSR getRequestHeader user: " + HSR.getHeader("x-remote-user"));
}
}

Micronaut - different validation for different operations

I have an JavaDTO like:
public class myDTO {
private String name;
private Integer age;
}
I want to do different validation in Micronaut by an CREATE operation and by an UPDATE operation. In Spring you can define different 'groups' therefore. See here stackoverflow link or here external link. So this looks like:
public class myDTO {
#Null(groups = OnCreate.class)
#NotNull(groups = OnUpdate.class)
private String name;
#Null(groups = OnCreate.class)
#NotNull(groups = OnUpdate.class)
private Integer age;
}
Is there something similiar for micronaut there?
I believe this is not Spring functionality but more how beans are validated from the javax bean validator.
You need to use Hibernate Validator where javax.persistence.validation.group.pre-update are applicable.
Default Micronaut bean validation is not using Hibernate Validator.
Try to add hibernate validator as dependency.
https://micronaut-projects.github.io/micronaut-hibernate-validator/latest/guide/index.html

does not have a corresponding accessor for data binding Play framework 2.5.3

I want to save user data to database. play version 2.5.3
I am getting this error:
JSR-303 validated property 'first_name' does not have a corresponding accessor for data binding - check your DataBinder's
configuration (bean property versus direct field access)]
My model class
#Entity
public class UserRegisterModel extends Model
{
#Id
#GeneratedValue
protected Long ID;
#Constraints.Required
protected String first_name;
protected String last_name;
protected String user_name;
#Constraints.Required
protected String password;
protected String password_confirmation;
#Constraints.Email
#Column(unique = true)
protected String email;
}
Controller class
public Result submitUserRegistrationForm()
{
play.data.Form<UserRegisterModel> form = play.data.Form.form(UserRegisterModel.class).bindFromRequest();
UserRegisterModel register = form.bindFromRequest().get();
}
Also I want to match password and conform password. I should do this in Model or controller.
Could you please provide me some sample code(Model,Controller) with form validation?
As discussed at the comments, you have to add play-enhancer as documented here:
https://www.playframework.com/documentation/2.5.x/PlayEnhancer#Setting-up
Also, the enhancer just works under the following conditions:
The enhancer looks for all fields on Java classes that:
are public
are non static
are non final
For each of those fields, it will generate a getter and a setter if they don’t already exist. If you wish to provide a custom getter or setter for a field, this can be done by just writing it, the Play enhancer will simply skip the generation of the getter or setter if it already exists.
So, you have two options here: keep the fields protected and write your own getters and setters or made the public and let the enhancer generate getters and setters required by other libraries (like form binding).

Creating other public methods in entity class

I have an Entity class
#Entity
#Table(name = "rule")
public class Rule implements Cloneable, Serializable, IPojoGenEntity, IRule, SequencedEntity {
private String name;
private Service service;
//getter .. setter for service and name
public String getServiceName() {
return (this.service.getName());
}
public void setServiceName(String servicename) {
this.service.setName(servicename);
}
}
I am getting exception for getting service name through RulClass object
public String getServiceName() {
return (this.service.getName());
}
Stack Trace
Caused by: com.ibm.db2.jcc.b.SqlException: "RULE0_.SERVICENAME" is not valid in the context where it is used.
at com.ibm.db2.jcc.b.fg.e(fg.java:1596)
at com.ibm.db2.jcc.b.fg.a(fg.java:1206)
at com.ibm.db2.jcc.a.gb.g(gb.java:140)
at com.ibm.db2.jcc.a.gb.a(gb.java:39)
at com.ibm.db2.jcc.a.w.a(w.java:34)
at com.ibm.db2.jcc.a.vb.g(vb.java:139)
Can we use such getter and setter in an entity class?
I am using hibernate, spring, DB2, IBM WebSphere
You should either make it #Transient as it was mentioned if you don't want to store it
OR
Define
#javax.persistence.Column(name = "service_id") field annotation for the getter to let hibernate know which column to use.
OR
Rename DB to have the service field "SERVICENAME" to use default column name
There is the Transient annotation to tell Hibernate to ignore a field. So:
#Transient
private Service service;
From very similar SO question: Make hibernate ignore class variables that are not mapped.
As serviceName was not a member of Rule class so there is a problem with method name. Name cannot be like
getServiceName
setServiceName
rather it should be something other than get or set prefix
fetchServiceName
addServiceName

Categories