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
Related
I have a Java Bean class which has some attributes having some Object type as datatype. Again that Object is having attributes which is again have some Object datatype and so on...
public class MyService {
private String id;
private String href;
private Category category;
}
public class Category {
private String id;
private Type type;
}
public class Type {
private String id;
private SomeObject someObject;
}
so on ...
Now I want to create JPA Entity classes for the class MyService with all the Mappings (OneToMany etc.). I know from database table we can generate the Entity classes but can we do it from the Java bean classes?
Because if I do manually it will take much time. So please suggest if I can generate those Entity classes or some other alternative ways instead of manually creating those Entity classes.
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();
}
Is there a class level annotation for jackson's #JsonProperty ? Without knowing what field names are in the class, I can be able to annotate the class with a annotation and it will map it for me automatically?
Currently I have to annotate each field with a JsonProperty, is there something I can do at the class level that servers the same purpose?
public class myEntity() {
#JsonProperty("banner")
private String banner;
#JsonProperty("menu")
private String menu;
}
Class level annotation
#JsonRootName("Response")
public class SuperResponse {
...
}
Result:
<Response>
...
</Response>
#JsonProperty is not class level annotation, and you don't need to mark your class with any annotation. If you provide your class name as an argument to parser it will know how to map it according to your getter methods. It is as if every getter method has been marked with #JsonProperty without any argument
#JsonRootName(value = "user")
public class User {
public int id;
public String name;
}
i want to use an enum in an entity bean. But the enum is in an embedded object. There is the code:
#Entity
#Table(name = "entity_foo")
public class EntityFoo implements Serializable
{
#Embedded
private EmbeddedFoo embeddedFoo;
public EmbeddedFoo getEmbeddedFoo()
{
return embeddedFoo;
}
public void setEmbeddedFoo(final EmbeddedFoo embeddedFoo)
{
this.embeddedFoo = embeddedFoo;
}
}
My Embedded Object includes the enum and looks like this:
#Embeddable
public class EmbeddedFoo implements Serializable
{
public static enum EnumBar {
VALUEA,VALUEB
}
private EnumBar enumBar;
#Enumerated(EnumType.STRING)
public EnumBar getEnumBar()
{
return enumBar;
}
public void setEnumBar(final EnumBar enumBar)
{
this.enumBar = enumBar;
}
}
In the table entity_foo i declared the value enumbar as varchar(255). Now i try to get data from the database.
final List<EntityFoo> entityFoos = query.getResultList();
This throws an PSQLException:
Caused by: org.postgresql.util.PSQLException: Bad value for type int : VALUEA
If i use the enum directly in the entity "EntityFoo" it works fine. This code runs on Wildfly 8.1 with Postgres 9.3 and Java 1.7
I hope i declared my problem clearly and anyone can help me.
UPDATE
Here is the link to a miniproject repository
https://github.com/MotherCake/miniprojct
To use this project you need a table. Here is the create statement.
CREATE TABLE "public"."minitable"(id int PRIMARY KEY NOT NULL,enumbar varchar(255));
CREATE UNIQUE INDEX minitable_pkey ON "public"."minitable"(id);
INSERT INTO minitable (id,enumbar) VALUES (0,'VALUEA');
INSERT INTO minitable (id,enumbar) VALUES (1,'VALUEB');
What i forgot to mention is that i'm using Toplink. I think Toplink causes the problem.
In the class Testservlet you can see 2 different ways to create a query. The exception i described is thrown if i use the createQuery(..) method with the setParameter(..) method. This is in the comment.
If i'm using the method createNativeQuery i get the result list and no exception is thrown. But after that i get a ClassCastException in class TestServlet.
The problem is that by default enums are persisted as int using oridinal. You have to change it to String representation by adding #Enumerated(EnumType.STRING) on enum field. Also check that in your main entity you've annotated fields instead of getter/setter so it turns on FIELD access on the entity as well as on embedded entity (in this case EmbeddedFoo). So if you annotate in EmbeddedFoo field instead of getter it will works correctly.
#Embeddable
public class EmbeddedFoo implements Serializable
{
public static enum EnumBar {
VALUEA,VALUEB
}
#Enumerated(EnumType.STRING)
private EnumBar enumBar;
public EnumBar getEnumBar()
{
return enumBar;
}
public void setEnumBar(final EnumBar enumBar)
{
this.enumBar = enumBar;
}
}
Also if you must have annotation on the getter for some reason you have to annotate EmbeddedFoo by #Access(AccessType.PROPERTY) and it'll also fix your problem.
#Embeddable
#Access(AccessType.PROPERTY)
public class EmbeddedFoo implements Serializable
{
public static enum EnumBar {
VALUEA,VALUEB
}
private EnumBar enumBar;
#Enumerated(EnumType.STRING)
public EnumBar getEnumBar()
{
return enumBar;
}
public void setEnumBar(final EnumBar enumBar)
{
this.enumBar = enumBar;
}
}
I found a solution to get the project work, but i dont know why this is necassary.
I thought, as Jakub wrote, that adding #Enumerated(EnumType.STRING) should be enough.
I annotated the variable enumBar with #Column(name = "enumbar").
#Column(name = "enumbar")
#Enumerated(EnumType.STRING)
public EnumBar enumBar;
Furthermore i add the #AtributeOverride annotation to the embedded object in EntityFoo
#Embedded
#AttributeOverride(name = "enumBar", column = #Column(name = "enumbar"))
private EmbeddedFoo embeddedFoo;
After that it works like charm.
I update the project on github for everyone who would like to try out.
Thanks for help.
I am trying to use an inner class as embeddable to represent some complicated properties of the outer class. When I store this, there is no information from the inner class in the database schema generated by eclipselink.
Does what I'm trying to do seem like a good idea? Why doesn't eclipselink seem to recognize them #Basic attribute on the getRate() in Attributes?
Some other info: Measure must be instantiated using a factory which is provided to the constructor of Person, so I don't even know how I'm going to be able to use this at all. It seems more and more likely that I'll have to make a separate class just to store the state of Person in simple terms (like doubles, not Measures) and use those to create the real Person-type objects, but that has very sad implications for the rest of my application.
#Entity
public static class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Transient
public Measure<Double, CleanupRate> rate;
#Embedded
private Attributes attributes;
#Embeddable
public static class Attributes {
#Transient
private Person person;
public Attributes() {
}
public Attributes(Person person) {
this.person = person;
}
#Basic
public double getRate() {
return person.rate.getInternalValue();
}
public void setRate(double value) {
person.rate.setInternalValue(value);
}
}
public Person() {
rate = udm.getMeasureFactory().createMeasure(0.0, CleanupRate.class);
attributes = new Attributes(this);
}
public void setRate(double rate) {
this.rate.setValue(rate);
}
}
Edit:
In order to inject the measure dependency into my objects when they are retrieved from storage, I've added an interface which injects the dependency and used it in my DAO. Since the DAO can be injected, I can propagate the dependency down to the retrieved objects. I got the idea from a blog.
private <T extends UomInjectable> List<T> //
getListOfUomInjectableType(final Class<T> klass) {
List<T> result = getListOfType(klass);
for (UomInjectable injectable : result) {
injectable.injectUomFactory(udm);
}
return result;
}
It is using the access type from the Person class, which is set to field, and so not seeing the annotation at the property level.
You will need to change the access type using Access(PROPERTY) on the embeddable class, and should remove the #Transient annotation on the person attribute.
I think in general you're going to be in trouble having Entities (Embeddable or otherwise) that need constructors with arguments. I'm not sure how that might be related to your schema generation issue, but I think this will be a problem trying to persist/retrieve these objects.
As you hinted, JPA requires all entity types to have a no-argument constructor. While your Attributes class has one, it leaves the 'person' field as null which will fairly quickly result in NPE's. Same with the Person constructor (maybe you left out the one that passes in 'udm' from the sample code?).
The set the Person for the Attributes, just use property access in Person and set it in your setAttributes method.
See,
http://en.wikibooks.org/wiki/Java_Persistence/Embeddables#Relationships