I really like where symfony 2 is headed, I just really dont like doctrine, I love codeigniters active record db system, is there anyway I can completely remove doctrine from symfony and replace it with a DAL like of codeigniters ?
Doctrine 2 is a pure Data Mapper pattern implementation. Its advantage over Active Record is that you don't have to bend your model to a database schema or vice versa. In most cases your model and schema may evolve separately; you'll need to update the mapping metadata only.
Plus you don't have to extend/implement any special classes/interfaces. Your model consists of POPOs (Plain Old PHP Objects) and the mapping is managed by an external object — an entity manager. This allows for good OO design on the PHP side and good schema design on the database side.
So, I suggest you rethink your desire to go back to Active Record. It may take some time for the paradigm shift but it's worth it.
The thing that Doctrine is a default choice doesn't mean it's the only one. It's not tightly coupled to Symfony and can be replaced.
Symfony provides sensible defaults but gives you the freedom to change them.
For example, you might use Propel. It implements Active Record (as opposed to Doctrine2).
You can write your own ORM implementation if you'd like to.
Note that apart from ORM, Doctrine has some useful helper libraries. For example annotation reader is used in Symfony to parse annotations. If you use them you'll need this part of Doctrine.
Related
I want to avoid getters/setters hell in my entities (here is the reason: http://ocramius.github.io/doctrine-best-practices/#/53), but both most popular admin panel generators:
Sonata and DoctrineORMAdminBundle
https://github.com/javiereguiluz/EasyAdminBundle
need getters and setters to render view.
My idea is to create DTO object instead (http://ocramius.github.io/doctrine-best-practices/#/57) and then use named constructors to create entities. I want to call named constructor inside my service. What is the best way to force admin panel generators to use my DTOs to persist/update data, can you give me an idea and/or example of good practices in that case?
The only way I imagined is to use DTO instead of real Entity, call prePersist/preUpdate hooks and use custom service, but it looks confusing.
One of the most important aspect of DDD is to correctly identify your bounded contexts (usually aligned with your sub-domains) and determine the appropriate technologies and architectures to use within those.
An admin panel sounds like something generic that would be very CRUD in nature. If that's the case then don't try to fight it and embrace CRUD within that BC. Trying to implement a pure domain model in a BC where it isn't needed would make things more complicated than they need to be.
However, if you determined that the complexity justifies a domain model then I would advise against using a code generator. Properly modeling the reality of a complex domain is not an easy task, and certainly not one that could be achieved by a tool.
I am looking for advise on how to develop a web application in Symfony2 by starting from a EER diagram. I appreciate a step-by-step primer of what you think is a reasonable way to develop.
Also, is there anything I should pay attention to avoid later failure?
Please suggest any tool I may use.
UPDATE: Let me clarify. Say I have the EER diagram below. A question is: is there a tool to convert it into symfony entity classes, with correct annotations about relationships (1:N, or N:M)?
To clarify even more.
Say I have developed a EER diagram as above.
By Workbench Export, I may get the sql queries to create the corresponding mySQL tables; hence I may use Doctrine/Symfony2's app/console doctrine:mapping:import to get a schema I may use to generate my Entity classes.
However all that is not exactly what I am looking for, since I would like to avoid that piece of reverse engineering. So, question is: is there a way to export a EER diagram to the Entity classes directly, and to leave mySQL table creation as really the last step?
If that is not really possible by Workbench/Doctrine/Symfony, is out there a different combination of tools which let me do so? (Zend; Ruby on Rails, ...)
UPDATE, it seems that Skipper Skipper does what I am looking for. Unfortunately it is not free/opensource (indeed a little pricey). Skipper has a export to ORM tool, which creates Entity classes for Doctrine (or other ORMs) from a EER diagram. I need to check how it performs with respect to relationships and annotations.
You can start from your EER diagram to define which doctrine entities your application is going to need and the relationship between them ( Note : If the relationships are not easy to spot you might need a class diagram ). Then I would suggest to follow an MVC design pattern for which Symfony is clearly oriented :
Once you have your entities you have your models.
Take a moment to define which routes your application is going to use
The easiest way to deal with controllers is to assign a different controller for each route (unless you really have a lot of routes)
Finally write your views to render your models and logic to the users.
Hope this helps.
Ocramius did in Doctrine ORM Module (for Zend Framework) a tool to visualize Entities diagram. It really helps to visualize the diagram to configure your objects relations...
I liked it in Zend, and used it a lot ! so I really missed it when I started to learn Symfony... I decided to find a way to do the same... and I did ! (it uses the yuml.me API)
I shared the bundle :
https://packagist.org/packages/onurb/doctrine-yuml-bundle
Installation is very easy in only 3 steps... Try it :)
I created a really nice script to do this. It converts the EER Diagram to Doctrine 2 entities which are symfony friendly and it allows you to totally customize how its done.
The first step is to download this tool (https://github.com/mysql-workbench-schema-exporter/doctrine2-exporter). I just installed it via composer (follow instructions on the github)
Next have the .mwb file be in the same directory as the script I am going to propose you make.
Next I created a script like this to customize the settings of that program.
autodoctrine.sh
php vendor/bin/mysql-workbench-schema-export youreerdiagram.mwb ./entities << EOF
`#Export to Doctrine Annotation Format` 1
`#Would you like to change the setup configuration before exporting` y
`#Log to console` y
`#Log file` doctrineconvert.log
`#Filename [%entity%.%extension%]`
`#Indentation [4]`
`#Use tabs [no]`
`#Eol delimeter (win, unix) [win]`
`#Backup existing file [yes]`
`#Add generator info as comment [yes]`
`#Skip plural name checking [no]`
`#Use logged storage [no]`
`#Sort tables and views [yes]`
`#Export only table categorized []`
`#Enhance many to many detection [yes]`
`#Skip many to many tables [yes]`
`#Bundle namespace []`
`#Entity namespace []`
`#Repository namespace []`
`#Use automatic repository [yes]`
`#Skip column with relation [no]`
`#Related var name format [%name%%related%]`
`#Nullable attribute (auto, always) [auto]`
`#Generated value strategy (auto, identity, sequence, table, none) [auto]`
`#Default cascade (persist, remove, detach, merge, all, refresh, ) [no]`
`#Use annotation prefix [ORM\]`
`#Skip getter and setter [no]`
`#Generate entity serialization [yes]`
`#Generate extendable entity [no]` y
`#Quote identifier strategy (auto, always, none) [auto]`
`#Extends class []`
`#Property typehint [no]`
EOF
This will create the doctrine entities for you. My particular settings turn on extendable entities because that way you can run this command over and over without overwriting model specific code. You just put your code in the class that is extending the base class. This will create a discriminator column in the database that you will want to ignore but its worth it for the logical separation.
Next you simply run the /vendor/bin/doctrine orm:schema-tool:create console command like in the symfony tutorials to have it create the database from the doctrine files! Let me know if this was clear enough.
References:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/tools.html
I have an existing sqlite db schema (about 30 table) which I have to import into my Android project.
I'd like to use greenDao in my code but I don't know how it's possible if I have already sqlite db created.
Is it possible to work with greenDao even if I haven't my pojo/entity class generated by greenDao Generator? Could I generate them manually?
I think I need also DaoMaster and DaoSession!??!
Thank you very much.
I've never done it, but theoretically, yes you can.
From greenDao FAQ page:
Can I use existing entity classes? Can I skip entity generation?
Yes. In your generator project, call setSkipGeneration(true) on entities you do not want to generate. Like this, you have the most possible control over your entities at the cost of manual maintenance. However, this is considered advanced usage and should be reserved for special cases only: the recommended way is to generate entities and use “keep sections” to inject custom code into them. If you choose to skip entity generation, you must either provide a constructor with all property fields in the order they were added in the generator project. Or alternatively, call setConstructors(false) on entities to make greenDAO use setters instead of the constructor to create entities.
I understand that you have to implement the generator project normally but skype de generation of the entities. This should generate the DaoMaster and DaoSession only.
I've got to the point with Symfony 2 / Doctrine 2 where I've come to realise that we have build too much business logic in our application into services & controllers - and not enough into the model.
We wish to introduce configuration to our models (to modify behaviour) potentially giving models access to services directly in order to carry out their behaviours.
I've noticed that the following question has the completely wrong answer marked as correct with 8 upvotes - so I know the approach we have taken up to now (anaemic model) is considered the 'correct' way to do things by a lot of Symfony 2 users. After reading more into domain driven design I know this is not the case.
Symfony2 MVC: where does my code belong?
I see a lot of bundles define the behaviour in the model and extend this in entities/documents. This pattern works to a certain extent - but I think we need to introduce an additional stage. Some of the behaviour of our models is optional and having that behaviour will depend on what additional bundles are registered in our application (so including X bundle will allow the application to do more things). An Example.
We have an order object which at the moment has a bidirectional relationship with entities in the courier bundle meaning there is a hard dependency. I want to decouple this and have the courier bundle(s) optionally add behaviour to the order. Consider this method call.
// no courier bundle is registered
$order->getShippingMethods();
// throws NoAvailableShippingMethodsException;
// one bundle registered
$order-getShippingMethods();
// returns an array with one shipping method
etc....
Now currently we have an OrderProvider service which just sits on top of the Entity Manager - so if you call
$orderProvider->GetOrder($id);
You just get the entity returned 'direct' from the database. My question here is what pattens are other people using here? I'm thinking about moving all 'business logic' into a model class that the entity extends, having the service layer pull the entity out (entity being dumb record with properties in the database and getters), and then configure the model using configuration (the configuration being injected into the OrderProvider service), which will modify the behaviour of the model. For the example given I might do something like (within the OrderProvider)..
// trimmed down for example purposes by removing exceptions etc.
public function getOrder($id)
{
$order = $this->orderRepository->findOneById($id);
if ($this->couriers){
$order->addCouriers($couriers);
}
return $order;
}
// this function would be called by the courier bundle automatically using semantic configuration / tags / setter injection
public function addCourier(CourierInterface $courier)
{
$this->couriers[] = $courier;
}
The other option that I have is to create a new type of object - which decorates the base order and is already configured (as it ITSELF will be defined as a service in the DIC) and inject the order into that. The difference is subtle and both approaches would work but I'm wondering which is the best path.
Finally I have one issue with all of this that I can't get my head around. If my base Order entity has relationships with other entities and THOSE entities need to be configured - where should this happen? For example if I access my customer thus.
$order->getCustomer();
I get the customer (entity). But It may be the case that I need to add some configuration to the customer object too - like
$customer->getContactMethods();
Now the behaviour of this method might differ depending on whether my application has registered a twitter bundle or a facebook bundle or something else. Given the above example I'm not going to get a sufficiently configured customer - but rather the 'vanilla' base entity. Only way I can see around this is to cut relationships between entities which require configuration and pull the entity from a CustomerProvider service:
$customerProvider->getCustomerByOrder($order);
This seems to me to be removing information from the model layer and moves back towards a reliance on using multiple services for simple tasks (which I'm trying to get away from). Thoughts and links to resources appreciated.
Edit: Relevant - I see the cons listed in the first answer every single day which is why I've asked this question -> Anemic Domain Model: Pros/Cons
It seems like a complexity of your project is the modularity requirement - application behavior must be extensible via bundles. I'm not familiar with Symfony 2 / Doctrine 2 but a typical DDD tactic is to try and make sure that domain entities such as Order and Customer are unaware of bundle configurations. In other words, surrounding services should not add bundle-specific behaviors to entities. Delegating the responsibility for bundle awareness to entities will make them too complex. Fabricating entity class hierarchies to support extensive behavior is also too complex. Instead, this extensibility should be managed by application services. An application service would determine which bundles are loaded and orchestrate the appropriate entities as a result.
Another strategic pattern to consider is bounded contexts. Is it possible to partition your application into bounded contexts which align with the modules? For example, to address the $order-getShippingMethods() method you can create two BCs, one where there is an order model that has a getShippingMethods() method and another without it. Having two models may seem like a violation of DRY but if the models represent different things (ie an order that has shipping data vs an order that doesn't) then nothing is actually repeated.
I have been reading about entity framework over the past couple of days and have managed to get a fair idea of using it but I still have a couple of questions some of which might seem a bit too basic. For perspective I am using entity framework 4.0 in an asp.net web application.If you can answer any of the questions please go ahead.
What advantage do I get by using POCO templates. I understand that if I wish to get persistence ignorance and keep my Entities clear of any information related to storage POCO entities are the way to go. Also I could switch from Entity framework to say NHibernate with relative ease when using POCO entities? Apart from loose coupling is there any significant reason for me to go towards POCO entities. Also if I do use POCO do I end up losing anything. I still get change tracking and lazy loading with the help of proxies?
Is it normal practice to use the Entities of the EF model as Data transfer Objects or Business Objects. i.e for example I have a separate class library for my entity model.Supposing I am using MVP , where I want a list of Employee's in a company. The presenter would request my business logic functions which would query the entity model for the list of Employee's and return the list of entities to the presenter. In this case my presenter would need to have a reference to the EF model. Is this the correct way? In the case of my asp.net web applciation it shouldnt be a problem but if I am using web services how does this work? Is this the reason to go towards POCO entities?
Supposing The Employee entity has a navigation property to a company table. If I use and wrap the data context in an 'using' block , and try to access the navigation property in the BL I am assuming I would get an exception. Would I also get an exception if I turned off lazyloading and used the 'include' linq query to get the entity? On a previous post someone recommended I use an context per request implying that the context remains active even when I am in the BL. I am assuming I would still need to detach the object and attach it to the context on my next request if I wish to persist any changes I make? or Instead should I just query for the object again with the new context and update it?
This question has more to do with organizing files/best practices and is a followup to a question i posted earlier. When I am using separate files based on entities to organize my data access layer, what is the best practice to organize my queries involving joins between multiple tables. I am still a bit hazy on organization. Have tried searching online but havent had much help.
Terrific question. My first recommendation is to think in patterns. With that said...
You pretty much nailed the advantages of using POCO. There are some distinct advantages to decoupling your business objects (POCO entities) from your data access layer. But the primary reason is like you said the ability to change or modify layers below. However using POCO you are essentially following the Code First (CF) approach. Personally, I consider it Code In Parallel depending upon your software development life cycle. You still have all the bells and whistles that data or model first approach have and some since you can extend the DbContext which is ObjectContext under the hood. I read an article, which I cannot seem to find, that CF is the future of Entity Framework. Lastly the nice thing with POCO is you are able to incorporate validation rules here or else where. You can also provide projections. Lets say you have Date of Birth but you want an Age property as well. That now becomes a no brainer as the Age property is ignored when mapping to the database.
Personally I create my own business objects (POCO) for large projects that tend to have a life of its own where change is a way of life. Another thought is scalability and maintainability. What if down the road I choose to split functionality between applications where, like you mentioned web services, functionality is now delivered from two disparate locations. If you have encapsulated your business objects and DAL within the same code block separation or scalability has now become a bit more complex. However, consider the project. It may be small with very little future change so no need to throw a grenade to kill a fly. At which time data first might be the way to go and let edmx file represent your objects. So don't marry yourself to one technology or one methodology/pattern. Do what makes sense for your time and business.
Using statements are perfectly fine. In fact I've recently been turned on to then wrapping that within a TransactionScope. If an error occurs rollbacks are inherent. Next, something to consider is the UnitOfWork. UnitOfWork pattern encapsulates a snapshot of what needs to be performed where the Data Context is the boundaries from which you work within. For each UnitOfWork you have a subject for which work is to be performed on. For example an Employee. So if you are to save Employee information to keep it simple you would make a call to the BL service or repository (which ever). There you pass in the Employee Id, perform some work under that UnitOfWork where it is either instantiated in the constructor or using Dependency Injections (DI or IoC). Easy starter is StructureMap. There the service makes the necessary calls to your UnitOfWork (DbContext) then returns control back upstream (e.g. UI).
The best way to learn here is to view others code. I'd start with some Microsoft examples. I'd start with Nerd Dinner (http://nerddinner.codeplex.com/) then build off that.
Additional Reading:
Use prototype pattern or not
http://weblogs.asp.net/manavi/archive/2011/05/17/associations-in-ef-4-1-code-first-part-6-many-valued-associations.aspx
[EDIT]
NightHawk457, I'm terribly sorry for not responding to your questions. Hopefully you figured it out but for future readers...
To help everyone visualize, imagine the below Architecture using the Domain Model and Repository as an example. Remember, there are many ways to skin a cat so take this and make it your own and don't forget my Grenade comment above.
Data Layer (Data Access): MyDbContext : DbContext, IUnitOfWork, where IUnitWork contracts the CRUD operations.
Data Repository (Data Access / Business Logic): MyDomainObjectRepository : IMyDomainObjectRepository, which receives IUnitOfWork by Factory class or Dependency Injection. Calls MyDomainObject validation on CRUD operations.
Domain Model (Business Logic): MyDomainObject using [Custom] Validation Attributes. Read this for pros/cons.
MVVM / MVC / WCF (Presentation / Service Layers): What ever additional layers you chose, you now have access to your data which is wrapped nicely in smaller modules who are self encapsulating of their function. The presentation layer (e.g. ViewModel, Controller, Code-Behind, etc.) can then receive an IMyObjectRepository by a Factory class or by Dependency Injection.
Tips:
Pass connection string into MyDbContext so you can reuse MyDbContext.
MySql does not play well with System.Transactions.TransactionScope, example. I don't recall exactly but it was something MySql did not support. This makes Testing a bit difficult since we have created this level of separation.
Create a Test project for each layer and at the minimum test general functionality/rules.
Each Domain Object should extend base object with ID field at minimum. Also do not implement Key attributes here. Domain Object should not describe architecture but rather the specific data as an entity. Even on Code First this can be achieved by the Fluent API.
Think generics when creating MyDbContext. ;) Read Diego's post.
In ASP.NET, the repositories are nice to use with ObjectDataSources.
As you can see, there is clear separation of roles where IUnitOfWork and IMyDomainObjectRepository are the Interfaces which expose the above layers functionality. And as an example, IUnitOfWork could be NHibernate, Entity Framework, LinqToSql or ADO.NET where a change to the factory class or dependency injection registration is all that has to change. FYI, I've heard the Repository called the Service Layer as well. Personally I like the first name to not be confused with Web Services. The next big take away from this structure is realizing the scope for you Database Context (IUnitOfWork). A simple example would be a ASP.NET page where for each page there is one and only one IUnitOfWork for either each repository or for that scope of work. Same holds true for ViewModels, Controllers, etc. So let's say you need to utilize two repositories, EmployeeRepository and HRRepository. You then could share the IUnitOfWork between both or not. To cross page, ViewModel or Controller boundaries, we use the ID for entities where they are then pulled from the DB and work is performed. You could alternatively pass a DTO across boundaries and attach to the context but then you begin losing separation of layers.
To continue, POCO classes do not have to be auto generated. In fact you can create your Entity Classes from scratch and perform the mapping in your extended DbContext class inside the OnModelCreating(DbModelBuilder mb) method. Start here, then here and note the Additional Resources, google Fluent API and read this post by Diego.
As for validation, this is an interesting point because it would be GREAT if all Business Rules could be validated in one location. Well, as we all know that doesn't work real well. So here is my recommendation, keep all data level validation (i.e. required, range, format, etc.) with data annotation as much as possible in the domain object and leave process validation in the Repository with clear roles of the Repository (i.e. if (isEmployee) do this, else that). I say clear, such that you do not want to add an Employee in two different Repositories where validation has to be duplicated. To call the validation, start here. Capture the ValidationResults and send upstream with a MyRepositoryValidationException which contains a collection of validations errors (e.g. Employee is required) which can be presented to the presentation layer. With all that said, don't forget to perform validation at the presentation layer. You don't want post backs to make sure an Employee has a valid Email, for example.
Just remember to balance time and effort with complexity. For something simple, use Data First or Model First with your EDMX file. Then lay a repository on top of that which also contains all the validation rules.