Is there a way to add more belongs-to relationships to an imported GORM domain class? Specifically, I'm attempting to use table-per-class to extend a shared subclass, but if I do this in two (or more) locations, and the locations do not have knowledge of each-other then things like:
set.addToParents(parentSet)
Start leading to:
org.hibernate.WrongClassException: Object [id=3482] was not of the specified subclass [com.acumenllc.domaincore.DbSet] : Discriminator: com.acumenllc.tickets.domain.TicketSet
happening everywhere.
A little more background, I'm working on a closure table to keep track of related objects. The base class recognizes the parent-child bi-directional relationship, as well as the ancestor-descendant extension of it. Different applications then extend this class with belongsTo relationships on objects to be represented as nodes in the resultant graph. We specifically want to be able to more-or-less ignore some of these other classes in other applications that happen to share the same database.
Ideally, it would be possible to import our base domain class into a new application and, rather than extending into a subclass, re-define the set of relationships that the base class recognizes in the scope of the application.
The only practical way I can see of doing this is with .hbm.xml files. The GORM approach of including hasMany/belongsTo in the code and JPA's approach using annotations are both fairly inflexible to support this sort of mapping. But if you separate the configuration from the code, you can define the relationships for different applications however you like. Creating a hibernate.cfg.xml file and the hbm.xml files is described here in the docs.
Related
I have a bunch of questions regarding Java 8 and SDN4. I created a model in Neo4j v3.0, played a bit with Cypher queries, and now moved to creating a Spring Boot application. As i started coding classes in Java, I've begun to rethink some of my model as well. Here's some questions in my mind (and I haven't found an example explaining this):
Do you need to use Interfaces in Java, with SDN?For eg. I'd code a Product interface and then have my products implement it, but is that how it's done when working with labels?
This is somewhat tied to my question on inheritance - I'd usually have a ProductFamily that my Product would inherit from. At the database level its modeled as (:Product)-[PartOf]->(:ProductFamily), but in the code these would not be super/sub class.
Any examples of using Generics in a graph context?
Is there a way to define constraints on what relationships a node can have and their direction in Java?
I understand there is probably not one right answer, but there's precious little on the web, so hope to get enlightened here!
If you had a Product interface annotated with #NodeEntity, then the you'll have the Product label in addition to the label on your implementing class, which I assume is what you want. If your interface isn't annotated, then your implementing classes will not inherit a label from it.
Not sure what you mean- if you say you have a ProductFamily that Product inherits from, but in the code it would not be a super/sub class?
Based on your graph model, if you want (:Product)-[PartOf]->(:ProductFamily) then you will have a Product class that maintains a reference to a ProductFamily class, and that reference annotated with #Relationship. If the Product class inherits from ProductFamily then persisting the Product will result in two labels- Product and ProductFamily because a Product IS-A ProductFamily.
How do you see yourself using generics- the answer really depends on that. Some cases are supported, some are not (an example of something not supported right now is equivalent of template.createRelationBetween in SDN4)
Yes, via the #Relationship annotation which accepts a type and direction. Note that this annotation only constrains your domain model, but you could very well flout this by creating relationships in another direction via a custom query.
So I want to create 3 plugins which include domain classes and a restful service, and who each build on top of each other.
Conceptually, they would "inherit" the base model this way:
Record > Person > User
However I have Read From The Friendly Manual that inheritance may cause some performance issues.
Then it crossed my mind that since Groovy has horizontal reuse capabilities (i.e. traits), I may very well just define everything in the trait and then implement the trait in the domain class.
Composing domain classes is not an option for me because of the renaming of the fields, and well, the loss of the convenience of IDE auto-completion.
My two questions are:
In what part of the Grails project structure would it be best to place these traits.
Can this cause different problems?
The Trait source code should be in
Grails 2: src/groovy/[package][whatever.groovy]
Grails 3: src/main/groovy/[package][whatever.groovy]
For example: src/main/groovy/com/my/package/foo.groovy
The main issue you'll have is that you'll loose the ability to perform polymorphic queries. For example, with inheritance you can do something like this:
def everything = Record.list()
and everything would contain Record, Person, and User instances. Kind of like a SQL union query. When using Traits instead of inheritance you loose this ability.
I am working on a grails project with potentially 36 domain classes each with a dozen plus unique properties and a handful of shared properties that can be inherited from a base domain class. The problem with this is that grails will generate 1 table with all the properties from all the domain classes that inherit from the base class. This means a table with well over 300 columns which seems problematic on multiple levels. The other route is to do away with inheritance and each domain represents a unique database table. No matter what, either a lot of time will be spent duplicating code or trying to manage the generated database. Is there another option that I am missing?
All thoughts and opinions welcome.
It would appear you are missing the all important tablePerHierarchy mapping value for domain classes. I highly recommend you read the Inheritance Strategies documentation regarding this.
From the documentation:
By default GORM classes use table-per-hierarchy inheritance mapping.
This has the disadvantage that columns cannot have a NOT-NULL
constraint applied to them at the database level. If you would prefer
to use a table-per-subclass inheritance strategy you can do so as
follows:
class Payment {
Integer amount
static mapping = {
tablePerHierarchy false
}
}
class CreditCardPayment extends Payment {
String cardNumber
}
The mapping of the root Payment class specifies that it will not be
using table-per-hierarchy mapping for all child classes.
Don't use inheritance between classes. It is very hard to make refactors in classes with inheritance.
You can use dynamic behavior for common classes through interfaces, or maybe re-think the design in the model classes.
I understand the fact that generating a model based on the DataBaseFirst method woill produce a collection of entitites on the ORM that are essentially mapped to the DB tables.
It is my understanding, that if you need properties from other entities or just dropdownlist fields, you can make a ViewModel and use that class as your model.
I have an AppDev course that I just finished and the author wrote something that if I understand it correctly, he is referring to change the ORM entities to fit what your ViewModels would look like, hence, no need for ViewModels. However, if you do this, and regenerate the ORM from the database, those new entities that you placed as "ViewModels" would be gone. If you changed the ORM to update the database, then your database structure in SQL Server would be "undone".
Please inform me if my understanding is correct that I simply need to use a ViewModel in a separate folder to gather specific classes and or properties in a superclass or a single class with the properties that I just need and use that as my model....
Here is the excerpt from the author:
EntityFramework is initially a one to one mapping of classes to tables, but you can create a model that better represents the entities in your application no matter how the data is stored in relational tables.
What I think the author may have been hinting at is the concept of complex models. Let's say, for instance, that in your Database you have a Customer Table and an Address Table. A one to one mapping would create 2 model items, one Customer class and one Address class. Using complex model mapping, you could instead create a single Customer class which contained the columns from both the Customer Table and the Address table. Thus, instead of Customer.Address.Street1 you could refer simply to Customer.Street1. This is only one of many cases where you could represent a conceptual model in code differently than the resulting data in storage. Check out the excellent blog series Inheritance with EF CodeFirst for examples of different mapping strategies, like Table Per Hierarchy (TPH), Table Per Type (TPT), Table Per Concrete Class (TPC). Note that even though these examples are CodeFirst, they still apply to Entity Framework even if the initial models are generated from a Database.
In general, if you use DatabaseFirst and then never modify the resulting entities, you will always have a class in code for each table in the database. However, the power of Enity Framework is that it allows you to more efficiently work with your entities by allowing these hybrid mappings, thus freeing you to think about your code without the extra burden of your classes having to abide by rigid SQL expectations.
Edit
When the Database-First or Model-First entities are generated, they are purposely generated as partial classes. You can create your own partials which extend the classes that are generated from Entity Framework without modifying the existing class files. If the models are re-generated, your partial classes will still be intact. Granted, using partials means that you have the Entity Framework default behaviors as well as your extended behaviors, but this isn't usually a huge issue.
Another option is that you can modify the TT files which Entity Framework uses to generate your models, ensuring that your models are always regenerated in the same state.
Ultimately, the main idea is that just because the default behavior of Entity Framework is to map the database to classes 1:1, there are other options and you are never forced into something that isn't efficient for your project.
What are the pros and cons of writing class methods in grails domain classes? I am asking, because I often do not see any grails projects with methods inside the domain classes, only data members. Is there a disadvantage to doing so?
When a domain class (not just in grails, but in object oriented programming in general), this is known as an anemic domain model. Martin Fowler proposes that domain logic gets put into the domain class to create a rich domain model. By doing this, domain classes become smarter and know how to perform operations, rather than having another service class that has to operate on the domain class. The pros of having a rich domain model is that the class encapsulates more of its own behavior, and it is more self contained. On the flip side, it does make the domain class more complex. Though I think the domain class should be more than just a business object.
In grails, I tend to try to use a combination of a rich domain model and using services. It's difficult to make a blanket statement as to when a method should be in a domain class and when it should be in a service. As a general rule though, if an operation is complex and requires multiple collaborators, I'll tend to put it in a service class. If the method seems like it should be behavior on the domain class, I'll put it there.
To give a more concrete example, let's take a Person class.
class Person {
String firstName
String lastName
List<Person> friends
}
In our application a person can speak. Now I can have a TalkService that knows how a person talks. But in this case, I think that talk is a core behavior of the person, so I would add a talk method to Person.
Let's say I also have functionality where I want to find all of the friends of friends of people (2nd degree friends). To me, this is not core behavior of a Person, so I woul delegate this out to a service.
To recap, in general I would add methods to the domain class when it is core behavior of the object (e.g. is it a domain method), otherwise, I would put it in a service.
In a Java project, you must have POJO classes that represents the model.
For example: Person, Invoice, Book, ...
Then there is the service layer, which contains interfaces for users to do some database queries, it takes in parameters your Model, and also return Model, and there is the controller layer which is responsible for redirection and inject your services.
In grails, this is very easy using injection of services into your controller
Now, when do we need to use methods inside the domain classes ? it's when only the model which responsible for what do we need to do, for example, how old is a Person X (it's from the date of birth), how many items exist in a Invoice (from the List), the think is we use that only when we manipulate the data of the current object.
For save method for example, you cannot add it in your model
PersonController :
def personService
def save() {
...
Person person = ...
personService.save(person);
...
}
This is more evolutive