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?).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With