I have a parent entity, Person, and two children entities : Caller and Employee. The two children share a lot of fields so i implemented JPA inheritance with single table strategy and discriminator column.So far so good.
In order to handle these objects i have some Service classes that handle database operations where i have methods like : getCallerById(); or getEmployeesByFirstName(). Also the save() methods are in these service classes. The problem is that when i want to save an employee or an caller i got a lot of duplicate code (for all the shared properties), so in order to prevent this i created a 3rd service: PersonService() in order to handle the common functionality. But now i do not know how to use this service in order to reuse as much code as i can.
Maybe in the PersonService() to have something like
public Boolean save(Person p){
if (p instanceOf Caller){
Caller c = new Caller();
c.setCallerSpecificProperty("XXX");
}
if (p instanceOf Employee){
Employee c = new Employee()
c.setEmployeeSpecificProperty("YYY");
}
c.setOtherCommonParameter("ccc");
//............
}
or how do you advise me to handle this problem???
Thanks
if your problem is just to set the 100 commonProperties of Person, you can add helper method, say
protected Person setCommonProperties(Person p){
p.setFoo(foo);
p.setBar(bar);
...
p.setWhatever(blahblah);
return p;
}
in your parentService( PersonService in your case)
And in your sub classes, (e.g. CallerService),
boolean save(){
Caller caller = new Caller();
caller = setCommonProperties(caller);
caller.setCallerPropertyA(...);
caller.setCallerPropertyB(...);
...
//save caller
return true or false;
}
Related
I am trying to wrap my mind around how I would go about implementing this specific problem. We have an external API that performs some logic and returns back the result of that logic. Unfortunately, the API returns a new object as the result as opposed to just the part that I am interested in. For example, the code would look something like this:
public class ComplexObject {
//lots of fields
}
public interface LogicApplier {
LogicResult applyLogic(ComplexObject obj);
}
public class LogicResult {
ComplexObject result;
public ComplexObject getResult();
}
public class FirstImplementation {
private LogicApplier _applier;
public Implementation(LogicApplier applier) {
_applier = applier;
}
public ComplexObject mainImplementation (ComplexObject apply) {
LogicResult logicResult = _applier.applyLogic(apply);
ComplexObject newComplexObject = logicResult.getResult();
//Do some other stuff with new ComplexObject
}
}
So question is: what would be the best way to put a limit on LogicApplier's "power" over FirstImplementation? For example, our motivation to call logic in the first place is to derive a missing field, let's say "name". This field could potentially be different in, say, SecondImplementation where that implementation is now looking to derive "street address" from LogicApplier API. However, there is nothing to stop LogicApplier from changing some other field, say "idNumber".
Is this best solved by a adding an interface for our specific implementations and manually mapping fields? Something like:
public interface SecondImplementationLogicApplier {
public String deriveAddress(ComplexObject o);
}
public class LimitedImplementationLogicApplier implements FirstImplementationLogicApplier, SecondImplementationLogicApplier {
LogicApplier _applier;
public LimitedImplementationLogicApplier(LogicApplier applier) {
_applier = applier;
}
public String deriveFirstName(ComplexObject o) {
LogicResult res = _applier.applyLogic(o);
return res.firstName;
}
public String deriveFirstName(ComplexObject o) {
LogicResult res = _applier.applyLogic(o);
return res.address;
}
}
I think you are on right track with your LimitedImplementationLogicApplier. You should guard objects in your domain from possible corruption from the outside. Only update fields that you need.
It looks like your ComplexObject is mutable. I'd consider hiding it behind the immutable interface (that don't have any setters or way to change the object exposed) and pass immutable interface into your LimitedImplementationLogicApplier so its got no chance of mutating ComplexObject.
If your API requires ComplexObject type and you can't change that, to prevent mutation you could:
Option 1
Create a clone of your base ComplexObject instance and pass it into the API. After you've got the result back, you update the needed fields on untouched base instance. This will work nicely if ComplexObject is "thing in itself" and changes in its state does not have side effects outside of the class instance, like changing databases or affecting other state.
If mutation of ComplexObject has side effects or may have them in future then its a real trouble.
Option 2
Inherit a ReadonlyComplexObject class from ComplexObject and pass that into the API. In ReadonlyComplexObject you will suppress all the behavior of the parent to prevent modification.
This is hacky in my opinion and will create more work later - if ComplexObject will be extended with new properties later you will need to make changes to ReadonlyComplexObject otherwise mutation will still occur.
I have a method like below:
#Override
public <T extends Entity> T saveOrHibernateUpdate(T entity) {
if (entity.getId() == null) {
persist(entity);
} else {
getSession().update(entity);
}
return entity;
}
I want to use getSession().merge(entity) instead of getSession().update(entity) inside else condition.
But this method is already being used by other applications. To not effect others, the entity which is passed to this method should still remain persistent, how can I achieve this when I am using merge instead of update? Because merge will not make the passed entity as persistent. Any ideas?
Example:
let's say someone is using previous version of this method like below
person.setName("ABC");// cosider person as a detached instance with a different name
saveOrHibernateUpdate(person);
person.setName("DEF") // They don't need to call the saveOrHibernateUpdate method again after this statement because person is a persistent object. But if I change the logic to use merge instead of update, then the users of this method would still see the name as "ABC". `So I need to make person object persistent somehow`
Hibernate merge() can be used to update values. Although this method creates a copy from the passed entity object and return it. The returned object is part of persistent context and tracked for any changes, passed object is not tracked. So you can do the following:
#Override
public <T extends Entity> T saveOrHibernateUpdate(T entity) {
if (entity.getId() == null) {
persist(entity);
return (T) entity;
} else {
Entity pEntity = (Entity) getSession().merge(entity);
return (T) pEntity;
}
}
By this way you will have the persistent object pEntity for many further manipulations.
I have an application that consumes incoming messages, parses the data present in the message, and then applies rules to that data. On the Rule entity, there's a column that distinguishes the type of rule.
I want to persist the Result of the rule to separate tables or subclasses, depending on what type of Rule processed them.
I'm currently solving this by creating a parent #MappedSuperclass (abstract) BaseResult object and an AppleResult and OrangeResult #Enitiy that extends the BaseResult.
My question is, given the statement below, how can I improve/annotate my objects in the model so that I don't have to do an instanceof check for each instance as I go to access/persist it? Right now this is what I'm having to do to avoid "baseresult does not exist" SQL grammar exceptions:
public void save(BaseResult baseResult) {
if (baseResult instanceof AppleResult) {
jpaApi.em().merge((AppleResult) baseResult);
} else if (baseResult instanceof OrangeResult) {
jpaApi.em().merge((OrangeResult) baseResult);
}
}
I'm hoping there's a more elegant solution than having to do a if/else and explicitly cast depending on the result. I've looking into using things like #DiscriminatorValue annotation of using Generics, but these all seem to require that the BaseResult in my case is also an entity, which it's not.
You should use #Inheritance. Then, saving would be as simple as:
public void save(final BaseResult baseResult) {
jpaApi.em().merge(baseResult);
}
Which inheritance strategy to use depends on your current database design, but I'm guessing that you have a table for each of the subclasses, so something like this:
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseResult {
//...
}
#Entity
public class AppleResult extends BaseResult {
//...
}
Having #Entity on the superclass is not a problem, as it is abstract anyways..
Also, using merge is usually something one shouldn't do, you should just manipulate your entities within a transaction and it's automatically persisted in the database upon commit of the transaction:
#Transactional //either this...
public void doStuff(final ResultCommand command) {
//begin transaction <-- ...or this
final BaseResult result = em.find(BaseResult.class, command.getResultId());
result.apply(command);
//end transaction
}
This is a question I always had, but now is the time to solve it:
I'm trying to implement the composition of objects using public attributes like:
Person {
public Car car;
}
Owner {
public Person person;
public Car car;
}
Car {
public Person person;
}
Really my question is: Is a good practice to set that composition properties public or private?
The difference:
a) Public: doing public, the access is fast and not complicated, because I only need to reference the property directly with the instance like:
$instancePerson.car.getNumberOfGearsGood()
The problem: the car propertie is available to be modified by anybody from anywhere.
b) Private: doing private, the access if slow and is necessary to use methods to get these properties like:
$instancePerson.getCar().getNumberOfGearsGood()
When I say slow is because you need to do a method two method call, while in the Public solution only you need to do one.
I know many developers and software engineers here will prefer Private solution, but can you explain the performance there?
If you are doing OO, there should be no such thing as a "public" attribute. All the attributes are implementation details of the object, therefore are hidden from everybody. Only the methods associated with the object's responsibility are public.
So to answer the question:
All "attributes" should be private
And there should be no getter on a private attribute
Yes, there should be no
person.getCar().getNumberOfGears();
This is sometimes called the Law of Demeter. The person should have methods that do stuff connected to the responsibility of the Person class, therefore there is no performance penalty accessing attributes, because this access is always internal to the class and direct.
the short answer is that, except for very few cases, you want those variables to be private, and often technologies in the JVM will make access faster than you think it would be (and sometimes even faster than in C/C++).
For a bit more detailed answer:
The main question is: who should be able to modify those variables? for example, you may want Car to be created passing a Person to its constructor, and never allow the person to change (in a world where there is no market for used vehicles). In this case, if the field is public another object can modify it and change the owner of the car. But if you make the field private, and provide a getOwner() method, nobody can modify it. If the get method is final, and therefore can't be overridden in a subclass, the JVM might even transform internally any invocation of x.getOwner() in the equivalent of x.owner. In your example however it's not possible to pass all elements in the constructor, as they reference each other. In fact, it seems to me your model has one too many classes. Let's try to write it a bit differently:
Person {
public Car car;
}
Car {
public Person owner;
}
Now, with assuming that every car has an owner, and every person own a car, this model is dangerous, because you could do something like this:
Person p = new Person()
Car c = new Car();
p.car = c;
As you can see, I forgot to set c.owner = p.
Let's see how we can fix this:
Person {
private Car car;
public void setCar(Car c) {
if (car == c)
return;
car = c;
c.setOwner(this);
}
}
Car {
private Person owner;
public void setOwner(Person o) {
if (o == owner)
return;
owner = o;
o.setCar(this);
}
}
I can now do :
Person p = new Person();
Car c = new Car();
p.setCar(c);
or
Person p = new Person();
Car c = new Car();
c.setOwner(p);
and either way both relationship will be set correctly.
In other words, being forced to go through accessors allows to set more than just a simple field, which is useful to establish coherent state across model elements involved in a relationship.
I'm creating an android game that uses an Entity object class that is then extended in many different types (i.e. enemies, bullets, etc). Is there a way to create a pool of type Entity and then transform the obtained Entity objects into whatever I need at runtime (say a bullet type)? Passing the entity as an argument to a constructor will just defeat the purpose of the pool correct? An example is below:
public class EntityPool extends Pool<Entity> {
public EntityPool (int initialCapacity, int max) {
super(initialCapacity, max);
}
protected PooledEntity newObject () {
return new PooledEntity();
}
public Entity obtain (int objectType) {
Entity ent = super.obtain();
if (objectType==SOME_OBJECT_TYPE)
//Do something to make ent into that object type
return ent;
}
public class PooledEntity extends Entity {
PooledEntity () {
super(null, 0, 0);
}
public void free () {
EntityPool.this.free(this);
}
}
}
The point of an object pool is generally to avoid system allocation and deallocation overheads and requires you know a "worst case" limit on the number of each type of entity you will want to allocate. So, assuming your entities are rather different in lifetime and usage, you probably want to have separate pools for each entity. (You can definitely improve the pool as in #zaske's answer.)
On the other hand, if you really want a single Entity pool, and you want to customize those entities at run-time, you could change from using Entity subclasses to something like:
class Entity {
EntityCustomizer custom;
...
}
Then when fetching an Entity out of the pool you pass in a Bullet or Ship or whatever customizer object:
public Entity obtain (int objectType) {
Entity ent = super.obtain();
if (objectType==SOME_OBJECT_TYPE)
ent.custom = EntityCustomizer.SOME_OBJECT_TYPE_IMPL;
return ent;
}
(I'm pretty sure this is a well-known pattern and I should be using the appropriate language to identify the parts ...)
All said, I think separate pools for each Entity type are the way to go, as my work-around is pretty hacky (you're trading a bunch of compile-time type checking for some run-time flexibility).
With your current code, your pool can store any object that is an Entity or of a sub class of entity. As a result, you can only use instanceof, or downcast to get the type of the concrete object.
If you would like to have different Pools per type, you can consider changing the declaration of the pool to :
public class EntityPool<T> extends Pool<T extends Entity>
And then for example have:
EntityPool<Bullet> bulletsPool = new EntityPool<Bullet>(); //only objects of Bullet of sub classes can be added