DataNucleus JDO reverse datastore 1:1 mapping with foreign keys - orm

I have a DataNucleus project and I am using JDO to reverse map a datastore to my classes. I do this very easily with:
package com.sample;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.PrimaryKey;
#PersistenceCapable(table = "source")
public class Source {
#PrimaryKey
private String source_id;
private Topic topic_id;
private String url;
private String description;
// getters and setters
}
public class Topic {
private String topic_id;
private String topicName;
private String topicDescription;
// getters and setters
}
The topic_id is a foreign key to another table, topic, which contains an id, a topicName, and a topicDescription.
I know that it is possible, using annotations, to return topic.id, topic.topicName, and topic.topicDescription with the topic_id. I just cannot figure out how, and I find the documentation to be a bit cryptic, especially for reverse mapping.
Can anyone lend a hand and provide an example? I've tried playing around with the #ForeignKey and #Element annotations, but I haven't had any luck yet.
Thanks!

If the "topic_id" is a FK to another object (which isn't posted), then the Java class should have a Topic object field in there, like any normal 1-1 (Object-Oriented) relation

Related

How to construct Spring Data repository query two Parameters with IN and same list?

This is my Entity:
#Data
#Entity
#IdClass(EtlJobExecutionTriggersId.class)
#Table(name = "ETL_JOB_EXEC_TRIGGERS")
public class EtlJobExecutionTriggers {
#Id private Long jobExecIdUs;
#Id private Long jobExecIdDs;
private LocalDate cobDate;
}
And here is the Composite Primary Key Class:
#Data
#NoArgsConstructor
#AllArgsConstructor
#Embeddable
#EqualsAndHashCode
public class EtlJobExecutionTriggersId implements Serializable {
private Long jobExecIdUs;
private Long jobExecIdDs;
}
And here is my Spring Repo:
public interface EtlJobExecTriggersRepo extends JpaRepository<EtlJobExecutionTriggers, EtlJobExecutionTriggersId> {
String SQL_ = "select o from EtlJobExecutionTriggers o where o.jobExecIdDs in (:ids) or o.jobExecIdUs in (:ids) order by o.jobExecIdUs, o.jobExecIdDs";
#Query(EtlJobExecTriggersRepo.SQL_)
List<EtlJobExecutionTriggers> findAllByJobExecIdDsInAndJobExecIdUsInSQL(#Param("ids") List<Long> jobExecIdList);
}
The #Query works as expected, but I would like not to write any SQL and instead express the same Query using only Spring Data repository query.
I have tried the following (and other variants)
List<EtlJobExecutionTriggers> findAllByJobExecIdDsInAndJobExecIdUsInOrderByJobExecIdUsJobExecIdDs(List<Long> jobExecIdDsList)
But i keep getting errors when Booting. The above interface method yields the following exception for the OrderBy part:
org.springframework.data.mapping.PropertyReferenceException: No property jobExecIdDs found for type Long! Traversed path: EtlJobExecutionTriggers.jobExecIdUs.
So what am I doing wrong here? or is it not possible to express this particular query via Spring Data Repo query?
As I have written in my comment I fixed the Order by issue, but I am still unable to make it work with only one method parameter (List jobExecIdList)
When I make it with two (List jobExecIdDsList, List jobExecIdUsList)
Like this:
List<EtlJobExecutionTriggers> findAllByJobExecIdDsInAndJobExecIdUsInOrderByJobExecIdUsAscJobExecIdDsAsc(List<Long> jobExecIdDsList, List<Long> jobExecIdUsList);
it actually works but I can't get to work with only one list, as in the #Query("....") method
I think using your own custom id generator conflicts with Spring Data Repository query.
// You shoud have two parameters in your method as below.
List findAllByJobExecIdDsInAndJobExecIdUsInOrderByJobExecIdUsJobExecIdDs(List jobExecIdDsList,List jobExecIdUsList);

Recommended strategy to use Value Objects for ID's in Spring Data

Using Value Objects can have a lot of advantages, especially when it comes to the type strictness of it. Using a PersonKey to use a Person (where the PersonKey really is a wrapped Long) is a lot safer than just using a Long or String as-is. I was wondering what the recommended strategy to deal with this in Spring Data is, however. Setting up the Repository is of course a matter of for example using
public interface PersonRepository CrudRepository<Person, PersonKey> {
}
but I was wondering what the best way to make the PersonKey class would be, having it map easily. Is there a better option than using an EmbeddedKey?
There is two annotations to do it : IdClass or EmbeddedId. I would recommend to use EmbeddedId because you don't have to repeat all of your attributes of your id class into your entity class.
Let's say you use EmbeddedId. It would looks like this :
#Embeddable
public class PersonKey {
private Long id;
}
#Entity
public class Person {
#EmbeddedId
private PersonKey personKey;
}
And you will access to your id like this :
select p.personKey.id from Person p
But with IdClass, your Person class would look like this :
#Entity
#IdClass(Person.key)
public class Person {
#Id
private Long id;
}
And you will access like this :
select p.id from Person p

JAXB serialization: Option to have a reference to inner objects

We are serializing a large number of objects. Some objects have attributes as list of objects.
I found an option in Texo serializer where such list of objects are saved as references and a lot of space is saved rather than showing same object multiple times. eg shown below:
<target:LogicalFact id="6022" version="28"
created="2014-12-01T15:53:59.000+0000"
logicalColumns="#/16651 #/10549 #/17142 #/16898 #/16542 #/16551 #/16832 #/16623 #/17230 #/16645 #/16393 #/16968 #/16575 #/17179 #/17195 #/16717 #/16636 #/16560 #/16410 #/16814 #/16610 #/16691 #/17173 #/16705 #/16838"/>
In above example, all logical columns are references. This saves space by avoiding duplicate information. Is there any such option available with JAXB serializer.
You are most probably interested in #XmlIDand #XmlIDREF which allow to reference objects.
#XmlAccessorType(XmlAccessType.FIELD)
public class Employee {
#XmlID
#XmlAttribute
private String id;
#XmlAttribute
private String name;
#XmlIDREF
private Employee manager;
#XmlIDREF
#XmlList
private List<Employee> reports;
public Employee() {
reports = new ArrayList<Employee>();
}
}
Please see this the following post by Blaise Doughan:
http://blog.bdoughan.com/2010/10/jaxb-and-shared-references-xmlid-and.html
The code snippet above is taken from this post.

Deserializing IEnumerable with private backing field in RavenDb

I've been modeling a domain for a couple of days now and not been thinking at all at persistance but instead focusing on domain logic. Now I'm ready to persist my domain objects, some of which contains IEnumerable of child entities. Using RavenDb, the persistance is 'easy', but when loading my objects back again, all of the IEnumerables are empty.
I've realized this is because they don't have any property setters at all, but instead uses a list as a backing field. The user of the domain aggregate root can add child entities through a public method and not directly on the collection.
private readonly List<VeryImportantPart> _veryImportantParts;
public IEnumerable<VeryImportantPart> VeryImportantParts { get { return _veryImportantParts; } }
And the method for adding, nothing fancy...
public void AddVeryImportantPart(VeryImportantPart part)
{
// some logic...
_veryImportantParts.Add(part);
}
I can fix this by adding a private/protected setter on all my IEnumerables with backing fields but it looks... well... not super sexy.
private List<VeryImportantPart> _veryImportantParts;
public IEnumerable<VeryImportantPart> VeryImportantParts
{
get { return _veryImportantParts; }
protected set { _veryImportantParts = value.ToList(); }
}
Now the RavenDb json serializer will populate my objects on load again, but I'm curious if there isn't a cleaner way of doing this?
I've been fiddeling with the JsonContractResolver but haven't found a solution yet...
I think I've found the root cause of this issue and it's probably due to the fact that many of my entities were created using:
protected MyClass(Guid id, string name, string description) : this()
{ .... }
public static MyClass Create(string name, string description)
{
return new MyClass(Guid.NewGuid(), name, description);
}
When deserializing, RavenDb/Json.net couldn't rebuild my entities in a proper way...
Changing to using a public constructor made all the difference.
Do you need to keep a private backing field? Often an automatic property will do.
public IList<VeryImportantPart> VeryImportantParts { get; protected set; }
When doing so, you may want to initialize your list in the constructor:
VeryImportantParts = new List<VeryImportantPart>();
This is optional, of course, but it allows you to create a new class and start adding to the list right away, before it is persisted. When Raven deserializes a class, it will use the setter to overwrite the default blank list, so this just helps with the first store.
You certainly won't be able to use a readonly field, as it couldn't be replaced during deserialization. It might be possible to write a contract resolver or converter that fills an existing list rather than creating a new one, but that seems like a rather complex solution.
Using an automatic property can add clarity to your code anyway - as it is less confusing whether to use the field or the property.

OO design of Books and Tags

I'm doing a basic exercise of object-oriented design for a simple use case: A Book can be tagged with many Tags.
I have many solutions, and I would like your input on which is better in term of OOD principles and maintanability.
Option 1
public class Book {
private String title;
//... other attributes
private List<Tag> tags;
}
The thing that bothers me is that we mixed core attributes of a Book with additional categorization or search data. I may have in the future a requirement where certain Books can't be tagged. In the future, the Book class can become bloated when I add more responsabilities: category, list of users that read it, ratings...
Option 2
public class TaggedBook extends Book {
private Book book;
private List<Tag> tags;
}
I think this is similar to the Decorator pattern, but I don't see it fit here because I'm not extending behavior.
Option 3
Decouple Books and Tags comnpletely, and use a service to retrieve Tags from a book (given each Book has a unique identifier)
List<Tag> TagService.getTags(Book book)
However, I don't find this solution very elegant (is it?), and I may have to send two queries: one to retrieve the book, the other for the tags.
I am planning on applying the best options to other requirements: A Book has a rating, a Book can be categorized...
I'm also planning on using a DMS to store Books and Tags objects. Since it's not a relations database, its schema will likely correspond to the class design.
Thank you
All three options can be valid and good choices for your class design. It all depends on the complete context/requirements. The requirement you listed are very likely not enough to make the "right" decision. For example, if your application is rather book centric and tags do not need to evolve or be authored independently from books, option 3 would probably introduce unnecessary complexity. If you design a public API that acts as a facade around your actual logic you still might go for option 1 or 2 even though internally both Book and Tag are totally decoupled aggregate roots. Scalability, performance, extensibilty ... those are all possible requirements that you need to balance and that will influence your design.
If you are looking for a good formalized methodology and guidance for class design for enterprise applications, I'd suggest you look into Domain Driven Design.
Also, do not design you classes for unknown future requirements. This will also again add useless complexity (think: cost). Just make sure you have enough unit test that cover your back when you need to refactor for new requirements.
The concept of decorator pattern fits well in your case.But I think strategy pattern
is more useful and effective in you case.If you don't know about strategy pattern then Take a look on This.It will give you a good idea on strategy pattern.If you need more suggestion or have any query then ask in comment.
Thank you
All the best..
If Books are not the only Entity in your Model that can be tagged. I'll go with this interface:
public interface Taggeable {
public List<Tag> getTags();
public void setTags (List<Tag> tags)
}
And
public class Book implements Taggeable {
//Book attributes and methods
The kinds of Books/Entities that can be Tagged only need to implement this interface. That way, you can have Book objects that allow tagging and others that doesn't. Also, the tagging mechanism can be used with other Objects of your model.
I think it would be better to mix pattern for a better solution. Remember a particular pattern only solves one particular problem.
My suggestion is to isolate different interfaces and join them accordingly. The base class should have the ability to query for supported interfaces, so that it can call the appropriate interface functions.
First interface is the query supported interface:
public interface QueryInterface {
public boolean isTaggable();
public boolean isRatable();
}
...next comes particular interfaces.
Suppose the first particular interface is taggable:
public interface Taggable {
public Vector<Tag> getTags();
public boolean addTag(Tag newTag);
}
...and the second one is rateable...
public interface Rateable {
public Rating getRating();
public void setRating(Rating newRating);
}
The plain old base class itself: :)
public class Book implements QueryInterface {
private String title;
public boolean isTaggable() {
return false;
}
public boolean isRateable() {
return false;
}
}
Now the special derived class which complies to the taggable interface:
public class TaggedBook extends Book implements Taggable {
private Vector<Tag> tags;
public Vector<Tag> getTags() {
return tags;
}
#override
public boolean isTaggable() {
return true;
}
public boolean addTag(Tag newTag) {
return tags.insert(newTag);
}
}
...and the different book which is rateable only:
public class RatedBook extends Book implements Rateable {
private Rating rating;
public Rating getRating() {
return rating;
}
public void setRating(Rating newRating) {
this.rating = newRating;
}
#override
public boolean isRateable() {
return true;
}
}
Hope this helps. :)
Option 1
The first solution supports the concept of a has-a relationship. I don't see that there is any drawback to this design. You say there is a possibility of code bloat when you add responsibilities to the class, however this is a completely separate issue (breaking the S in SOLID). A class with many members is not inherently a bad thing (It can sometimes be an indication that something has gone wrong, but not always).
The other problem you give is that in the future you might have a Book without Tags. Since I do not know the whole picture I am only guessing, but I would argue strongly that this Book would/could simply be a Book with 0 Tags.
Option 3
I think that this is the non OO way of doing things. Implementing a has-a relationship by association of some ID. I don't like it at all.
For each additional property you wanted to add to a Book you would need to also create an appropriate Service type object and make lots of additional and unnecessary calls with no benefit for doing so over Option 1 that i can see.
Another reason that i don't like this is that this implies that a Tag has a has-a relationship with books. I don't think that they do.
Option 2
This is not good in my opinion, but that is mostly because i think the decorator pattern was not designed for use in this sort of situation, and because you would likely need to make use of rtti to be able to use your resulting objects, or implement a lot of empty methods in your base class.
I think that your first solution is overwhelmingly the best. If you are worried about code bloat you may consider having a Tags object as a member of Book, which is responsible for searching itself (This also helps with the S in SOLID) and the same for any additional properties of Book. If a Book has no tags then Tags would simply return false when queried, and Book would echo that.
Summary
For such a simple problem, don't over think it. The basic principles of OO design (has-a, is-a) are the most important.
I would suggest to think about it as a design problem first, and then try to express the design in code.
So, we have to decide what classes (entities) we have. The Book is a class because is central to the problem, has distinct instances and, probably, several attributes and operations. The Tag may be both a value-object and a class.
Let us consider the first option. It can be a value object because it does not have internal structure, any operations, and its instances may not be distinct. Thus a Tag can be thought of as a String marker. This way, Book has an attribute, say, tags that contains a collection of tag values. Values can be added and removed without any restrictions. Books can be searched by tags where tags are supplied by value. It is difficult t get a complete list of tags or get all books for a specific tag.
Now, the second option. The Tag can also be a class because it is related to another class (Book) and its instances may be distinct. Then we have two classes: Book and Tag, and a 'many-to-many' association between them - TaggedWith. As you may know, association is a sort of a class itself besides being a relation. Instances of TaggedWith association (links) connect instances of Book and Tag. Next we have to decide which class will be responsible for managing correspondence (create, read, lookup, destroy, update...) between Book and Tag. Most natural choice here is to assign this responsibility to the association TaggedWith.
Lets write some code.
Option 1
public class Book {
private Collection<String> tags;
/* methods to work with tags, e.g. */
public void addTag(String tag) {...}
public String[] getAllTags() {...}
...
}
It may look complex, but actually similar code can just be generated from the design description in a couple of mouse clicks. On the other hand, if you use DB a lot of code here becomes SQL queries.
Option 2
public class Tag {
/* we may wish to define a readable unique id for Tag instances */
#Id
private String name;
/* if you need navigation from tags to books */
private Collection<Book> taggedBooks;
public Collection<Book> getTaggedBooks() {...}
public void addBook(Book book) {...} // calls TaggedWith.create(this, book)
public void _addBook(Book book) {...} // adds book to taggedBooks
....
/* I think you get the idea */
/* methods to work with tags */
public String getName() {...}
...
/* Tags cannot be created without id (i.e. primary key...) */
public Tag(String name) {...}
/* if you'd like to know all tags in the system,
you have to implement 'lookup' methods.
For this simple case, they may be put here.
We implement Factory Method and Singleton patterns here.
Also, change constructor visibility to private / protected.
*/
protected static HashMap<String, Tag> tags = ...; // you may wish to use a DB table instead
public static Tag getInstance(String name) {...} // this would transform to DAO for DB
}
public class Book {
/* if we need an id */
#Id // made up
private String bookId;
/* constructors and lookup the same as for Tag
If you wish to use a database, consider introducing data access layer or use ORM
*/
/* if you need navigation from Book to Tag */
private Collection<Tag> tags;
public Collection<Tag> getTags() {...}
...
}
public TaggedWith {
/* constructor and lookup the same as for Tag and Book (!) */
/* manage ends of the association */
private Book book;
private Tag tag;
public Book getBook() {...}
public Tag getTag() {...}
protected TaggedWith(Book book, Tag tag) {
this.book = book;
this.tag = tag;
book._addTag(tag); // if you need navigation from books to tags
tag._addBook(book); // if you need navigation from tags to books
}
/* if you need to search tags by books and books by tags */
private static Collection<TaggedWith> tagsBooks = ...;
public static TaggedWith create(Tag tag, Book book) {
// create new TaggedWith and add it to tagsBooks
}
}
I prefer the 3rd option, to separate them completely.
Books and tags have a mang-to-many relationship, by separating them, you can make it easier to make queries like "which books got tagged by 'Computer Science'".
Unless either the order of the tags on a book matters or a book can have the same tag twice, you should store your tags in a set rather than a list.
Once you've done that, I'd go with something like the third option. It seems to me that the books don't own the tags and the tags don't own the books (indeed, you'd want to look this up either way, probably). Later, when you want to associate other things with your books (e.g. reviews, ratings, libraries) you can create another association without modifying the book class.
I would do it totally different. Thinking a bit like labels in Gmail, I would make it so it would be easier to actually look for books with certain tags rather than find what tags are on the book. Namely, tags work as a filter to find books, not the other way around.
public interface ITaggable
{
string Name { get; }
}
public class Book : ITaggable
{
}
public class Tag
{
private List<ITaggable> objects;
private String name;
public void AddObject() {}
public void RemoveObject() {}
public void HasObject() {}
}
public class TagManager
{
private List<Tag> tags;
private void InitFromDatabase() {}
public void GetTagsForObject(o: ITaggable) {}
public void GetObjectsForTag(objectName: String) {} //
public void GetObjectsForTag(t: Tag) {} //
public void GetObjectsForTag(tagName: String) {} //
public void GetAllTags();
}
... somewhere else ...
public void SearchForTag(tag: Tag)
{
TagManager tagManager = new TagManager();
// Give me all tags with
List<ITaggable> books = tagManager.GetObjectsForTag("History");
}