How do you put defaults values from application.properties to an Entity?
This works but is not what I need.
#Entity
#Data
public class SomeEntity {
private String value = "default";
}
I know that this code doesn't work because I've used new(), so Spring doesn't inject the value. Adding #Component didn't change.
#Entity
#Data
public class SomeEntity {
#Value("${value}")
private String value;
}
//other place
SomeEntity se = new SomeEntity()
System.out.println(se.value); //null
how can i add ${value} to something like this?
(I like this way because database knows the default value too)
#Entity
#Data
public class SomeEntity {
#Column(columnDefinition = "varchar(255) default [INJECT_HERE]");
private String value;
}
You cannot inject properties in an Entity via Spring because you create it yourself. If you really want to have a default value driven by a property, I would do a factory with the injected value that creates those SomeEntity and set the given property with the right field.
Related
Preferably, using the #Indexed annotation, or some other declarative way, is it possible to inject a system property, preferably using SPeL.
I have tried the following but found expireAfterSeconds gives error because it wants an int:
#Data
#Document(collection = "#{#xyzUpdates.collectionName}")
public class UpdatesFromXyz {
#Id
#Field("resourceId")
private UUID resourceId;
#Indexed(expireAfterSeconds = "#{#xyzUpdates.maxRecords}")
private LocalDate updateDate;
}
and my properties class:
#ConfigurationProperties("xyz.updates")
#Getter
#Setter
#Component
public class XyzUpdates {
private String collectionName = "updatesFromXyz";
private int maxRecords;
}
Since SpringData MongoDB 2.2 you can use expireAfter which accepts numeric values followed by their unit of measure or a Spring template expression.
I have SuperClass where I have defined my properties and I want to apply one more annotation on one of the SuperClass Property.
#MappedSuperclass
public class CartBaseEntity {
private String cartName;
#Column(name = "cart_name")
public String getCartName() {
return cartName;
}
public void setCartName(String cartName) {
this.cartName = cartName;
}
}
And my Sub Class is in below:
#Entity
#Table(name = "CART2")
public class CartEntity extends CartBaseEntity implements Serializable {
private Set<Items> items;
#Basic(fetch = FetchType.LAZY)
#Override
public String getCartName() {
return super.getCartName();
}
}
I was trying to override the 'cartName' column and want to add #Basic annotation on it. Is it possible or is there any workarround? TIA
Yes, it's possible with #AttributeOverride annotation applied to a subclass:
#Entity
#Table(name = "CART2")
#AttributeOverride(name = "cartName", column = #Column(name="CART_NAME"))
public class CartEntity extends CartBaseEntity implements Serializable {
...
}
UPDATE: here's what JPA 2.1 Specification tells about overriding a column in a mapped superclass:
11.1.4 AttributeOverride Annotation
The AttributeOverride annotation is used to override the mapping of
a Basic (whether explicit or default) property or field or Id
property or field.
The AttributeOverride annotation may be applied to an entity that
extends a mapped superclass or to an embedded field or property to
override a Basic mapping or Id mapping defined by the mapped
superclass or embeddable class (or embeddable class of one of its
attributes).
I am working on a Java web application that I think use Hibernate and I am not so into Hibernate so I have the following doubt:
I have a model class named ReaDichiarazioneIntento that map a database table named REA_DICHIARAZIONE_INTENTO, something like this:
#javax.persistence.IdClass(it.enel.wearea.entity.ReaDichiarazioneIntentoPK.class)
#javax.persistence.Table(name = "REA_DICHIARAZIONE_INTENTO", schema = "EDIWEA")
#Entity
public class ReaDichiarazioneIntento implements Cloneable {
private Integer idDichiarazione;
#javax.persistence.Column(name = "ID_DICHIARAZIONE")
#Id
public Integer getIdDichiarazione() {
return idDichiarazione;
}
public void setIdDichiarazione(Integer idDichiarazione) {
this.idDichiarazione = idDichiarazione;
}
private Integer idCliente;
#javax.persistence.Column(name = "ID_CLIENTE")
#Basic
public Integer getIdCliente() {
return idCliente;
}
public void setIdCliente(Integer idCliente) {
this.idCliente = idCliente;
}
...................................................................
...................................................................
...................................................................
SOME OTHER FIELDS AND RELATED GETTER AND SETTER METHODS
...................................................................
...................................................................
...................................................................
}
Ok I have some doubts about this class. My doubt are:
1) Is it using Hibernate for mapping the class to the database table? Or what? I know that to map a database table to a class I have to do something like:
#Entity
#Table(name = "REA_DICHIARAZIONE_INTENTO")
Why in this project do:
#javax.persistence.IdClass(it.enel.wearea.entity.ReaDichiarazioneIntentoPK.class)
#javax.persistence.Table(name = "REA_DICHIARAZIONE_INTENTO", schema = "EDIWEA")
#Entity
What is the difference between the #Table(name = "REA_DICHIARAZIONE_INTENTO") annotation and the #javax.persistence.Table(name = "REA_DICHIARAZIONE_INTENTO", schema = "EDIWEA") annotation (used in my project)?
2) The second doubt is related to this annotation:
#javax.persistence.IdClass(it.enel.wearea.entity.ReaDichiarazioneIntentoPK.class)
What exactly means?
3) The last doubt is related to the mapping between a class field to a table column on the DB. Why is it done only on the getter method and not directly on the field name?
Tnx
It is using JPA annotations, and Hibernate is a JPA implementation. JPA by itself is just a set of interfaces/annotations, while JPA implementation (like Hibernate) provides meat around those interfaces/annotations. There is no difference between the two annotations, other than specified schema. Hibernate also has its own #Table annotation but it is used for additional information supplied by JPA'a #Table annotation
#IdClass means that the complex primary key is used for this entity
Specifies a composite primary key class that is mapped to multiple fields or properties of the entity.
You can annotate fields or properties (getters), it's up to you. But, #Id mapping dictates what is valid, meaning if you put #Id on field then you must put all other mappings on fields also, and vice versa.
This is using JPA, looks like, not hibernate. Here is the difference according to SO and here is another link
I have the following object structure:
#Document(collection = "user")
#TypeAlias("user")
public class User {
#Id
private ObjectId id;
private Contact info = new Contact();
}
and here is the Contact pojo:
public class Contact {
#Indexed(unique = true)
private String mail;
}
But for some reasons not known to me, I don't see Spring-data creating a unique index for the property info.mail
To summarize, I have this json structure of user object:
{_id:xxxxx,info:{mail:"abc#xyz.shoes"}}
And I want to create a unique index on info.mail using Spring data with the above pojo structure. Please help.
As far as I remember, annotating embedded fields with #Indexed will not work. #CompoundIndex is the way to go:
#Document(collection = "user")
#TypeAlias("user")
#CompoundIndexes({
#CompoundIndex(name = "contact_email", def = "{ 'contact.mail': 1 }", unique = true)
})
public class User {
#Id
private ObjectId id;
private Contact info = new Contact();
}
In my case I had a fresh spring boot application 2.3.0 with just #Document, #Id and #Indexed annotations. I was able to retrieve and insert documents but it refused to create the index other than the PK. Finally I figured that there is a property that you need to enable.
spring.data.mongodb.auto-index-creation = true
As a matter of fact it even works on nested objects without #Document annotation.
Hope this helps :)
Obsolete answer, this was with and older version of mongodb 1.x.
Had the same issue, it seems that your Contact class is missing the #Document annotation i.e.
#Document
public class Contact {
#Indexed(unique = true)
private String mail;
}
Should work, quote from the spring mongodb reference
Automatic index creation is only done for types annotated with #Document.
Extending #Xenobius's answer:
If any configuration extending AbstractMongoClientConfiguration is set, MongoMappingContext will back off. The result is:
spring.data.mongodb.auto-index-creation = true will not be effective
You will need add this into your own configuration:
#Override
protected boolean autoIndexCreation() {
return true;
}
ref: https://github.com/spring-projects/spring-boot/issues/28478#issuecomment-954627106
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