Unable to persist objects in GAE JDO - java

I am completely fresh to both JDO and GAE, and have been struggling to get my data layer to persist any code at all!
The issues I am facing may be very simple, but I just cant seem to find any a way no matter what solution I try.
Firstly the problem: (Slightly simplified, but still contains all the info necessary)
My data model is as such:
User:
(primary key)
String emailID
String firstName
Car:
(primary key)
User user
(primary key)
String registration
String model
This was the initial datamodel. I implemented a CarPK object to get a composite primary key of the User and the registration. However that ran into a variety of issues. (Which i will save for another time/question)
I then changed the design as such:
User: (Unchanged)
Car:
(primary key)
String fauxPK (here fauxPK = user.getEmailID() + SEP + registration)
User user
String registration
String model
This works fine for the user, and it can insert and retrieve user objects. However when i try to insert a Car Object, i get the following error:
"Cannot have a java.lang.String primary key and be a child object"
Found the following helpful link about it:
http://stackoverflow.com/questions/2063467/persist-list-of-objects
Went to the link suggested there, that explains how to create Keys, however they keep talking about "Entity Groups" and "Entity Group Parents". But I cant seem to find any articles or sites that explain what are "Entity Group"s or an "Entity Group Parents"
I could try fiddling around some more to figure out if i can store an object somehow, But I am running sort on patience and also would rather understand and implement than vice versa.
So i would appreciate any docs (even if its huge) that covers all these points, and preferably has some examples that go beyond the very basic data modeling.
And thanks for reading such a long post :)

I'm afraid you won't like the answer. GAE JDO has to be used a very specific way and is fraught with limitations that you have to observe to use it effectively. Read the docs forwards and backwards. For the issue you are seeing now, you probably need to read this section a couple of times:
http://code.google.com/appengine/docs/java/datastore/relationships.html
GAE JDO has owned and unowned relationships. See the documentation above for examples of owned vs unowned. I believe you want Car and User to have an unowned relationship. Note this revelation in the Google App Engine documentation about unowned relationships:
http://code.google.com/appengine/docs/java/datastore/relationships.html#Unowned_Relationships
In addition to owned relationships, the JDO API also provides a facility for managing unowned relationships. The App Engine implementation of JDO does not yet implement this facility, but don't worry, you can still manage these relationships using Key values in place of instances (or Collections of instances) of your model objects.
This essentially means, to use GAE JDO, you should not use a direct reference for an unowned relationship like between the Car and User classes. Rather, you should use indirect references between them, i.e. Car should have a field for the User's key rather than a direct reference to the User itself. Some of the trouble you are having is because GAE JDO cannot deal with how you are modeling this relationship in code.
Asker goes on to say:
Went to the link suggested there, that explains how to create Keys, however they keep talking about "Entity Groups" and "Entity Group Parents". But I cant seem to find any articles or sites that explain what are "Entity Group"s or an "Entity Group Parents"
Entity Group - a graph of objects that were initially persisted together. For example, because Car refers directly to a User, when you persist a given Car instance for the first time, then you would also persist the User instance to which it refers and this Car instance and this User instance would be part of the same entity group. If this User instance was already been persisted, either independently by itself or as part of another Car instance, then this User instance is already in another entity group. "Owned" relationships are supposed to be in the same entity group. Note that GAE JDO transactions can modify only 1 entity group - any more will raise an exception.
Entity Group Parent - a top-level/root ("parent") persisted class. In the above example, when you persist a given Car instance for the first time, you would also persist the User instance it refers to. The Car instance is the entity group parent. An "owned" "child" class like User embeds its parent's (Car's) key within its own (User) key. If you were to pull a Car instance from the database and then attempt to access the User that this Car refers to, then the GAE JDO will use the Car's key to find the corresponding User (because the target User's key has the parent Car's key embedded as part of its own key).
Asker got this error message:
"Cannot have a java.lang.String primary key and be a child object"
Note this statement in the docs:
The child class must have a key field whose type can contain the parent key information: either a Key, or a Key value encoded as a string. See Creating Data: Keys for information on key field types.
This means that "child" classes must use certain types of keys (i.e. keys that are capable of encapsulating their parent's key within the child's key). Long and String are suitable for entity group parents classes, i.e. non-child classes. However, "child" classes must use either Key or Key encoded as String type for their key. The error message indicates that the Car class refers to the User class as if it were an "owned" "child" class, and therefore the User class must use an key type appropriate for a child, but the User class is not using a key type appropriate for a child (non-encoded String).
The fix for the immediate problem at hand is to model Car and User to be an unowned relationship by changing Car from having the direct reference to User to instead having an indirect reference by storing the related User's key. The overall fix will likely include taking a hard look at how to fit your object model into GAE JDO's framework (once you wade through the docs to try to understand it). This will likely include having to manually manage some of the relationships between the classes.
If its any consolation, I'm dealing with the same sort of issues with GAE JDO myself (I even have a Car class too!).

Read http://code.google.com/appengine/docs/java/datastore/relationships.html

Related

Best approach for linking diverse entity types in JPA

Short version for the hasty:
There's various tables/entities in my domain model which have the same field (a UUID). There is a table where I need to link rows/instances of such entities to other JPA-managed entities. In other words, the instance of the field in that link table won't be known up-front. The two approaches I can think of are:
Use an abstract entity and a TABLE_PER_CLASS strategy, or
use an #MappedSuperClass store the class name of the instance in the link table as well, or something similar that lets me define logic for getting the actual instance from the right table.
Both have advantages and disadvantages in terms of complexity and performance. Which do you believe to be best, is there maybe a third option, or have you tried something like this in the past and would advice/strongly warn against?
Long version in case you want more background:
I have a database/object model wherein many types have a common field: a universally unique identifier (UUID). The reason for this is that instances of these types can be subject to changes. The changes follow the command model and their data can be encapsulated and itself persisted. Let's call such a change a "mutation". It must be possible to find out which mutations exist in the database for any given entity, and vice-versa, on which entity a stored mutation operates.
Take the following entities with UUIDs as an (extremely simplified) example:
To store the "mutations", we use a table/entity called MutationHolder. To link a mutation to its target entity, there's a MutationEntityLink. The only reason this data isn't directly on the MutationHolder is because there can be direct or indirect links, but that's of little importance here so I left it out:
The question comes down to how I can model the entity field in MutationEntityLink. There are two approaches I can think of.
The first is to make an abstract #Entity annotated class with the UUID field. Customer, Contract and Address would extend it. So it is a TABLE_PER_CLASS strategy. I assume that I could use this as a type for the entity field, although I'm not certain. However, I fear this might have a serious performance penalty since JPA would need to query many tables to find the actual instance.
The second is to simply use #MappedSuperClass and just store the UUID for an entity in the entity field of MutationEntityLink. In order to get the actual entity with that UUID, I'd have to solve it programmatically. Adding an additional column with the class name of the entity, or something else that allows me to identify it or paste it in a JPQL query would do. This requires more work but seems more efficient. I'm not averse to coding some utility classes or doing some reflection/custom annotation work if needed.
My question is which of these approaches seems best? Alternatively, you might have a better suggestion, or notice I'm missing something; for example, maybe there's a way to add a type column even with TABLE_PER_CLASS inheritance to point JPA to the right table? Perhaps you've tried something like this and want to warn me about numerous issues that would arise.
Some additional info:
We create the database schema, so we can add whatever we want.
A single table inheritance strategy isn't an option. The tables must remain distinct. For the same reason, joined inheritance doesn't seem a good fit either.
The JPA provider is Hibernate and using things that are not part of the JPA standard isn't an issue.
If the entities don't have anything in common besides having a uuid I'd use the second approach you describe: use MappedSuperclass. Making the common superclass an entity would prevent you to use a different inheritance strategy if needed, would require a table for that super entity even if no instances exist and from a business point of view it's just wrong.
The link itself could be implemented in multiple ways, e.g. you could subclass MutationEntityLink for each entity to map (e.g. CustomerMutationEntityLink etc.) or do as you described it, i.e. only store the uuid as well as some discriminator/type information and resolve programatically (we're using that approach for something similar btw.).
You need to use #MappedSuperclass while inheriting associations/methods/properties whereas TABLE_PER_CLASS is generally used when you have entity and sub-entities. If there are entities having an association with the base class in the model, then use TABLE_PER_CLASS since the base class behaves like an entity. Otherwise, since the base class would include properties/attributes and methods which are general to such entities not related to each other, using #MappedSuperclass would be a better idea
Example1: You need to set alarms for some different activities like "take medicine", "call mom", "go to doctor" etc. The content of the alarm message does not matter, you will need a reminder. So use TABLE_PER_CLASS since alarm message, which is your base class is like an entity here.
Example2: Assume the base class AbstractDomainObject enables you to create login ID, loginName, creation/modification date for each object where no entity has an association with the base class, you will need to specify the association for the sake of clearing later, like "Company","University" etc. In this situation, using #MappedSuperclass would be better.

Hibernate Mapping

I have an issue in performing Hibernate Mapping. The scenario is as follows:
There is a User class which has username, name, dateofbirth, image and other information pertaining to a user with username as the primary key.
Second class is Product class which has product id and other information related to a product with primary key as product key.
The third class is Order class which has OrderId, OrderDate, Username- should be foriegn key-referring to the User class username and finally a Set of type Product- because one order can have many products.
Now I want the primary key of the Order class as a composite key (OrderId, ProductID) and this productID should be reference from Product Class.
The relationships that I want to create are as follows:
1. One order can belong to only one User
2. One order can have many products
Can someone lead me on how to go about it? Any kind of help will be great.
I think most likely you are thinking similar relationship. Difference in your requirement is you need One to Many mapping from Order/PurchaseOrder to Product/Item and you don't want Shipment.
My suggestion would be:
Create bi-directional one-to-many relationship b/w User and Order. Benefit for bidirectional is you can access User Object from Order Object, if not required, you can keep it unidirectional from User to Order.
Create one-to-many relationship b/w Order and Product.
Instead of composite key in order, keep the primary key as just OrderID. You can still fetch list of products from your order object and order object from user object.
The whole point in making this decision is from which object you derive remaining objects. With ORMs you should know from which object you would derive rest and so my suggestion is based on assumption that you will have User object available as attached entity, so you can get list of orders (defined as set) and from a particular order find out list/set of Products.
In case you have Order object available first, then create a bidirectional with User. So that you can find list/set of Products at one end, and Customer associated at other.
For ORM mappings refer Hibernate Mapping Examples.
Hope this clarifies.

Entities in domain driven design

I am reading Eric Evans book about DDD and I have a question to the following quote. How do you make your equals() method when you should not use the attributes? I am using JPA and I have a id attribute which is unique but this is not set until you actually persist the entity. So what do you do? I have implemented the equals method based on the attributes and I understand why you shouldn't because it failed in my project.
Section about entities:
When an object is distinguished by its identity, rather than its
attributes, make this primary to its definition in the model. Keep the
class definition simple and focused on life cycle continuity and
identity. Define a means of distinguishing each object regardless of
its form or history. Be alert to requirements that call for matching
objects by attributes. Define an operation that is guaranteed to
produce a unique result for each object, possibly by attaching a
symbol that is guaranteed unique. This means of identification may
come from the outside, or it may be an arbitrary identifier created by
and for the system, but it must correspond to the identity
distinctions in the model. The model must define what it means to be
the same thing.
http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215
Couple approaches possible:
Use a business key. This is the most 'DDD compliant' approach. Look closely at domain and business requirements. How does your business identify Customers for example? Do they use Social Security Number or phone number? How would your business solve this problem if it was paper-based (no computers)? If there is no natural business key, create surrogate. Choose the business key that is final and use it in equals(). There is a section in DDD book dedicated to this specific problem.
For the cases when there is no natural business key you can generate UUID. This would also have an advantage in distributed system in which case you don't need to rely on centralized (and potentially unavailable) resource like database to generate a new id.
There is also an option to just rely on default equals() for entity classes. It would compare two memory locations and it is enough in most cases because Unit Of Work (Hibernate Session) holds on to all the entities (this ORM pattern is called Identity Map). This is not reliable because it will break if you use entities that are not limited to the scope of one Hibernate Session (think threads, detached entities etc)
Interestingly enough, 'official' DDD sample uses a very lightweight framework where every entity class is derived from Entity interface with one method:
boolean sameIdentityAs(T other)
// Entities compare by identity, not by attributes.
If the object is not persistent yet, then is there any harm in comparing 2 objects based on their attributes?
I am not sure why this failed in your project, but in my experience, comparison based on attributes almost always is slippery slope if your attributes are not final. That means, 2 objects that are equal now, may not be equal after sometime. This is very bad.
Given that most Java classes are written along with their accessors, equals comparing attributes are said to be a bad idea.
However, I would probably first check to see if the ID field is not null. If it is null, I would fall back to attribute comparison. If it is not null, then just use it and not do anything else. Does this make sense?
Given Person class with attributes name, surname. When Person at the age of 21 changes its name is it still the same Person (equals gives true)?
If you write equals basis on attributes, then, it would not be the same person, so in my opinion the best approach is to test equality of entities basis on their business identifier (unique and immutable over the whole entity lifecycle).
Another solution could be to use an UUID field in your entity.
In this case, you could use the UUID as primary key or just for equals.
#Entity
public class YourEntity{
#Id
private String uuid = UUID.randomUUID().toString();
// getter only...
}

DDD: Entity and its identifier

I have an entity in my system, which naturally needs an identifier so that it can be uniquely identified. Assuming the database is used for generating the identifier with Hibernate, using the native strategy, then obviously the application code is free of this responsibility of assigning identifiers.
Now, can an instance of that entity be considered valid before it is persisted and gets its identifier?
Or should I use some other strategy to assign my entities their identifiers so that it gets its identifier when its constructor is called?
That's an extensive topic, but here are two possibilities:
define your hashCode() and equals(..) contracts based on business keys. For example, for a User entity, this would be the username, rather than the auto-generated id. Thus you will be able to use the entity in collections before it is persisted
use UUID as a primary key, and handle the generation yourself. See this article by Jeff Atwood and this article demonstrating a way to use it with Hibernate
(Since you mention DDD and hibernate, take a look at this article of mine)

Hibernate -using Table per subclass - how to link an existing superclass object to a subclass object

I have a User hibernate class, Clerk class and Consumer class. All these maps to their own tables in database. The User PK also acts as Clerk's and Consumer's PK.
So now my problem is that if a user is initially a Clerk, he has a record in Users table and Clerks table. If that user wants to become a consumer, I want to link that User's record to the new Consumer's record. So even if I pass the userId to the consumer's record, it treats it as a new User to be persisted and gives a duplicate_key exception. How do I tell Hibernate to link the same user object with this new Consumer object?
No, you can't. You are trying to implement multiple inheritance. A User cannot be both a Clerk and a Consumer in a language that does not support multiple inheritance. If this is a valid scenario, then you should map using composition rather than inheritance, so that your User class has both Clerk and Consumer child objects, either or both of which could be null.
With your current implementation, I think that you'll have to delete the actual Clerk and to persist a new Consumer, after having copied the desired attributes (and this makes sense IMO as you can't cast a Clerk into a Consumer and vice versa). If you use a functional key for your User (as you should), this shouldn't be a problem.
In my experience the best approach is to think of objects and classes first, and then see what hibernate generates out of that.
When stating your in terms of java you have multiple inheritance (which only works a little with interfaces) and mutating type, i.e. your User is first a clerk an later a consumer. Doesn't work this way.
Consider this model instead:
a User has a map of Role-classes to (subclasses of)Roles. Clerk and Consumer are roles. When you let a role have a backreference to the user, the user can work as a delegate to provide the attributes and methods every user has.
In code this would look similar to this:
class User {
Map,Role> roles;
<T extends Role> T as(<Class<T>> roleClass>){
return (T) roles.get(roleClass);
}
Should be nice, clean and flexible. And pretty easy to map to a database schema with hibernate.

Categories