MongoDB Auto-Incrementing id field with java mongo driver? - java

Whole day I have tried to find a answer on the question:
"How to add auto-Incrementing "id" field in an Entity class?".
I am using Morphia (a type-safe java library for Mongo DB). After a couple hours of digging in source code and googling I have found a LongIdEntity class in org.mongodb.morphia.utils package. Based on this class I have implemented the following solution. See below:
City class:
#Entity
public class City {
#Id
private Long id;
}
Hotel class:
#Entity
public class Hotel {
#Id
private Long id;
}
CityLongIdEntity class:
public class CityLongIdEntity extends LongIdEntity {
public CityLongIdEntity(Datastore ds) {
super(ds);
}
}
HotelLongIdEntity class:
public class HotelLongIdEntity extends LongIdEntity {
public HotelLongIdEntity(Datastore ds) {
super(ds);
}
}
DAO implementation:
CityDAO class:
public class CityDAO extends BasicDAO<City, Long> {
public CityDAO(Datastore ds) {
super(ds);
}
#Override
public Key<City> save(City c) {
if (c.getId() == null) {
CityLongIdEntity ent = new CityLongIdEntity(getDs());
getDs().save(ent);
c.setId(ent.getMyLongId());
}
return getDs().save(c);
}
}
HotelDAO class:
public class HotelDAO extends BasicDAO<Hotel, Long> {
public HotelDAO(Datastore ds) {
super(ds);
}
#Override
public Key<Hotel> save(Hotel h) {
if (h.getId() == null) {
HotelLongIdEntity ent = new HotelLongIdEntity(getDs());
getDs().save(ent);
h.setId(ent.getMyLongId());
}
return getDs().save(h);
}
}
Or you can see all this code on the Github
The UML diagram is also available:
All this code works as expected and I am happy, but I have a couple questions:
As you can see, for each Entity I need to create additional Entity, for example: for entity City I created CityLongIdEntity (this entity is crucial part of auto-incrementing functionality) . In this case, if my app will have 20 Entities (City, Address, Hotel, User, Room, Order etc.) I will need to create a 40 classes! I am afraid, but I think it will be "Code smell". Am I right?
Also, the Entity doesn't know about EntityNameLongIdEntity and EntityNameLongIdEntity has no idea who is Entity. And only specific EntityDAO class combines ans uses those classes together. Is it ok? Or it is again code smell?
Each EntityDAO class overrides extends BasicDAO class and overrides method save(). The difference between overrided methods save() for different DAO classes is minimal. I am afraid. that is code duplication and code smell again. Am I right?
please provide your opinion.

We require numeric IDs on some entities, but our implementation is a little different:
We use a regular ObjectId on all entities. Where required, we add a numeric ID.
There is a dedicated AutoIncrementEntity, which keeps a counter for different keys — that would be your class name.
We don't use DAOs but a generic save method, where we check if we have an instance of a class with a numeric ID. If that ID hasn't been set, we fetch one and update the AutoIncrementEntity. The relevant method isn't used at the moment — let me know if it's totally unclear and I'll finish that code.
Two more things from my implementation, which might be a little confusing:
You can always provide a starting number, so our numeric IDs could be 1000, 1001, 1002,... instead of 1, 2, 3,...
The key in the AutoIncrementEntity isn't required to be a class, it could also be a subset. For example, you want to number employees within a company, then the key for employees of company A would be employee-A, for company B company-B,...

Related

Hibernate: How to model an Inheritance type structure and do operations without explicit casting

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
}

OOP - How does one class become another?

A person has an ID.
A student has a student's ID.
A driver has a driver's license.
A person attends a school and becomes a student.
A student graduates and becomes an ordinary person.
A person gets a driver's license and becomes a driver.
A student gets a driver's license and becomes a driver.
Are those things just state change like in the following example:
class Person {
ID id;
StudentID stId;
DriverLicense license;
void drive() {
if(license == null) //illegal state exception
//drive
}
//bla bla
}
Or is there inheritance? Since an object is data+behavior, new data and being able to do new things should warrant a new object
class Student extends Person {
//
}
class Driver extends Person {
//
}
//things get messy here, in Java you can't extend multiple class
//what if there's a rule that, student drivers can request/get a tax reduction?
class DriverStudent extends Person, Driver {
//
}
PLUS, more importantly, how does one become the other? Through methods or constructors or 3rd classes(like a service or aggregate) ?
class Person {
Driver getADriversLicense() {
//create and return a Driver
//this person still exists but now there's a driver with this person's data
}
}
or:
class Driver extends Person {
public Driver(Person p) {
//constructor
}
}
or:
class Aggregate {
Driver giveDriversLicense(Person p) {
// access internal state of both objects(ditch encapsulation) and return a driver?
// put aggregate in same package with Driver and Person and use package private methods to provide encapsulation?
}
}
A better way to see such relationship is through roles i.e. a Person can play multiple roles .
How about a scenario where a Person can be a Driver and a Student and may be an Employee too ?
So IMO its best represented as following -
class Person{
List<Role> currentRoles ;
List<Role> getCurrentRoles(){
return currentRoles ;
}
public void addRole(Role role){
currentRoles.add(role) ; // so on
}
}
Using generics and type safe casts you can easily retrieve a specific role and invoke a related operation on it.
public interface DriverRole implements Role {
License getDriversLicense() ;
}
Edit : Taking it further to answer your question fully it easily addresses a scenario where Person gains or loses a Role i.e. add or remove a Role. As pointed out in the comment here this relationship is best represented through Has <0..M> relationship then IS - kind of relationship.
Edit 1 In comparison when you use a Decorator pattern your origin gets wrapped and too many decorators can create a aggregation chain which IMO is not an ideal scenario or alternatively it will result in a decorator inheritance chain which is not to my liking.
Having said that depending on a specific scenario one particular pattern might fit better then the other though in the example you have given I think a simple aggregation of Roles is best.
Inheritance is one way to think of these relationships but this only practically makes sense when it's reasonable to enumerate the number of combinations of statuses the person might have.
Another to think of this without constraining yourself through inheritance is to think of everyone as people with different credentials.
Rather than a person being a driver, think of everyone as a generic Person having a set of credentials. eg. a drivers license, and also having a student ID. Then you can represent all of these different credentials that a person may have through a Credentials class (which Driver, Student, etc) extend. A person may have a List which you can use to perform any case based logic that you might want.
As you mentioned, consider using inheritance to approach this problem. Each Student and each Driver are both considered a Person. Therefore, both Student and Driver should inherit functionality from the parent class, Person. As far as whether someone is a student, driver, both, or just an "ordinary person" should simply be stored in a variable.
public class Person
{
private int id;
private String type;
public Person(int id, String type)
{
this.id = id;
this.type = type;
}
public int GetID()
{
// Using *this* keyword for consistency, but not necessary here.
return this.id;
}
public void SetID(int id)
{
this.id = id;
}
public String GetType()
{
// Using *this* keyword for consistency, but not necessary here.
return this.type;
}
public void SetType(String type)
{
this.type = type;
}
}
public class Student extends Person
{
super(int id, String type);
}
public class Driver extends Person
{
super(int id, String type);
}
public class Main
{
public static void main(String [] args)
{
Student sam = new Student(342918293, "student");
Driver rosa = new Driver(147284, "driver");
}
}
I'n not too fond of this being an inheritance, as a Person can be a Driver AND a Student at the same time.
Though I don't fully rememeber how the decorator pattern (sugested by Mr. Poliwhirl) works, that may be the correct approach.

Spring Data Neo4j: How do I pull a list of nodes of which I do not know the type?

I'm using Spring Data Neo4j and I'd like to pull a list of owners. An owner can be a :Person (human) or an :Entity (company). I'm not sure what Type<T> should be. I could use in the GraphRepository<Type> interface.
My Query is:
MATCH ()-[r:OWNED_BY]->(o) RETURN
And this is the code I tried:
public interface Owners extends GraphRepository<Object> {
#Query("start o=MATCH ()-[r:OWNED_BY]->(o) RETURN o;")
Iterable<Object> getOwners();
}
I had an idea that I could perhaps extend a common base class, such as PersistentBaseObject with an id and a name, or an interface like HasIdAndName. Not sure how I'd integrate this though,
Yes,you could extend a common base class, perhaps like this-
public class Owner {
Long id;
String name;
...
}
public class Person extends Owner {
private int age;
...
}
public class Entity extends Owner {
private String location;
...
}
And add a matching repository for Owner
public interface OwnerRepository extends GraphRepository<Owner> {
}
which will allow you to do stuff such as ownerRepository.findAll()
But since you're using a #Query, there is no reason you can't put this method on even the PersonRepository (at least in SDN 4. I'm not sure about SDN 3.x)
#Query("start o=MATCH ()-[r:OWNED_BY]->(o) RETURN o;")
Iterable<Owner> getOwners();
Note however, that now your Person and Entity nodes are going to have an extra Owner label.
EDIT:
The additional label can be avoided by changing Owner to an interface.
Then the #Query on a repository returning a collection of Owner should still work.

interpretation of attached UML diagram in Java Pseudocode?

I would like to translate the attached UML to Pseudocode. I have the following class and interface headers below.
I would like to know
1) if this is correct?
2) what is the relation between Store and Manager and Store and StoreEmployee?
I have Manager and StoreEmployee as private fields in Store. Is this correct?
if yes, then why they are not included in attributes
3)What is the relation between store and Store Test ?
4) I have Employee as interface while PayRoll Record as concrete class?
Is this correct? both have broken line arrow connection?
public interface Employee { }
public class Manager implements Employee{ }
public class StoreEmployee implements Employee{ }
public class SalesAssociate extends StoreEmployee { }
public class PayrollRecord { } //
public class Store extends PayrollRecord { } // does it have Manager and StoreEmployee as private fields
public class StoreTest { } //does it have Store as private field
Here are some quick answers that don't fulfil your questions perfectly, while still hopefully point you in the right direction.
You have your extends mixed in with your composed of. Check your UML documentation again. So, no you are incorrect.. but also correct in some places. :)
A Store has a single manager (if there is not a number attached, then it is assumed to be a 1..1 relationship).
Look at how you used the same arrow in previous solutions.
Yes, look at the heads of the arrows. The Employee implies inherits from, where the PayRollRecord is just a general usage arrow.
For these, the previous answers should help you answer your questions here. :)
public class Store extends PayrollRecord { } // does it have Manager and StoreEmployee as private fields
public class StoreTest { } //does it have Store as private field

How do Generics and Fields assist DAO Pattern in Standalone Java applications

//Interface DAO
public abstract class BaseDAO<T extends BaseDTO> {
public void update(T t) throws DBException {
Field[] fieldsToInsert = t.getClass().getDeclaredFields();
//code to update database object academic or event
}
public Integer create(T t) throws DBException {
Field[] fieldsToInsert = t.getClass().getDeclaredFields();
//code to create academic or event in database
}
}
//Concrete DAOs
public class AcademicDAO extends BaseDAO<AcademicDTO> {
//provide implementation
}
public class EventDAO extends BaseDAO<EventDTO> {
//provide implementation
}
//Transfer object
public class AcademicDTO extends BaseDTO {
String title;
String surname;
//getters and setters
}
public class BaseDTO {
protected Integer ID;
public Integer getID() {
return ID;
}
public void setID(Integer ID) {
this.ID = ID;
}
}
Hello Guys, I have a sample code on me that follows the above structure to create a small java application to manage academics and events. It is leniently following this pattern
1- You experts are familiar with this pattern more than me. I would like to understand why generics are used in this case so DAOs can extend and implement a generic base class. It would be great if one can show how generics here may be advantageous using an example.
2 - I have also witnessed the use of java Fields. Is there a link between generics and Fields?
I would like to document DAO pattern in an academic report, but I am finding difficult to understand how Generics and Reflect Field play a part here. Do they support flexibility and loose coupling?
The code you've provided is reusable set of logic to load and persist entities. Many times, in an application of non-trivial size, you'll wind up persisting many different types of objects. In this example, you can define as many objects as necessary, but only define the logic to actually save and load once. By asking the DTO what Field objects are there, it can get at the data to help construct queries for loading and saving.
Generics allow you to use this pattern while maintaining type safety. AcademicDAO can only handle AcadmeicDTO. You can't use AcademicDAO to store EventDTO. Generics allow the instance of the class to rely on a more specific type when dealing with the Field objects. If you didn't have generics, the BaseDAO would take Object, and you wouldn't be able to access any methods except those that Object provides because the JVM wouldn't know what class is provided, so it has to limit it's knowledge to that of Object. Using getClass().getDeclaredFields() bypasses that limitation because getClass() returns the actual class of the Object parameter.
Field is just a way to use reflection to access the values of the properties in each DTO. If you had to access the fields directly, with getTitle(), you couldn't reuse a generic base class to do your persistence. What would happen when you needed to access EventDTO? You would have to provide logic for that. Field allows you to skip that logic.
Edit:
To explain what I mean by accessing getID, you could do the following within BaseDAO because T is known to be a BaseDTO with a getID() method defined:
public abstract class BaseDAO<T extends BaseDTO> {
public boolean update(T t) throws DBException {
Integer id = t.getID();
Field[] fields = t.getClass().getDeclaredFields();
// Assuming you have a db object to execute queries using bind variables:
boolean success = db.execute("UPDATE table SET ... WHERE id = ?", id.intValue());
return success;
}
}
If you had this instead (in a non-generic class):
public boolean update(Object o) throws DBException {
// This line doesn't work, since Object doesn't have a getID() method.
Integer id = t.getID();
Field[] fields = o.getClass().getDeclaredFields();
boolean success = db.execute("UPDATE table SET ... WHERE id = ?", id.intValue());
return success;
}
You'd have to look through those Field objects, or ask for the ID field and assume it existed.
For question 1. The use of generics allows the same implementations of update and create to be used regardless of the type of the DTO. Consider if you didn't use generics. Then the best you could do for the parameter type of update would be BaseDTO, but then you could call
academicDAO.update( eventDTO )
which doesn't make sense. With the code as you have it, this would be a type error. So the main advantage is: better type checking.
For question 2. The use of Fields allows a single implementation of update and create to work on DTO object of various concrete types.

Categories