seam-gen doesn't generate #ManyToMany relation - seam

I am having problems generating a app(using "seam generate" after "seam create-project")
With identifying relationship like Role , User and User_has_Role.
It generates the 3 one-to-many , many-to-one entities instead of 2 #manytoMany entities.
I have seen a similar question here seam-gen doesn't generate EntityQuery interfaces for #ManyToMany members
In this post here, he managed to generate many to many entities http://community.jboss.org/thread/146500
Can seamgen generate many-to-many entities ?
If i use hibernate tools separately it generates the entities correctly.
I used seamgen 2.2.1CR2

Ok, so this is not possible to do with seam-gen as the question you are linking too.
This is how to do it manually (which is very easy).
In your User.java entity, write the following.
#UserRoles
#ManyToMany
#JoinTable(name = "UserRoles", joinColumns = #JoinColumn(name = "userId"), inverseJoinColumns = #JoinColumn(name = "roleId"))
public List<Role> getRoles() {
return roles;
}
This should be enough to generate/map the UserRoles table for you

Related

Virtual many-to-many relationship

let's imagine two distinct entities A and B is it possible to create a kind of virtual many-to-many relation.
I want A able to get all the B by id and B to get all A without using a join table.
I want to do this trick because my entities are not related. So, I can only access B from A using:
->join('App:entityB','b')
But this is not working using the normalizer.
I want my normalizer came from A to B and using a doctrine criteria in A to filter my B collection
/**
* #return mixed
*/
public function getEntitiesA()
{
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('foo', 'foo'));
return $this->entitiesA->matching($criteria);
}
I have found resolve_target_entity on the symfony documentation can I use this for my purpose?
resolve_target_entity

Doctrine "A new entity was found through the relationship" error

First off I want to say I've read through all the docs and googled this plenty before posting this question. I know what that error means (un-persisted entity in a relationship)
I'm getting this error where I think I shouldn't be getting it.
I have a OneToMany Bi-Directional relationship as follow:
Class Channel
{
/**
* #ORM\OneToMany(targetEntity="Step", mappedBy="channel", cascade={"all"}, orphanRemoval=true)
* #ORM\OrderBy({"sequence" = "ASC"})
*/
protected $steps;
}
Class Step
{
/**
* #ORM\ManyToOne(targetEntity="Channel", inversedBy="steps")
*/
protected $channel;
}
One Channel can have many Steps and the owning side is Channel. After I upgraded from Doctrine 2.4 to 2.5 I'm getting this error:
Doctrine\ORM\ORMInvalidArgumentException: A new entity was found
through the relationship 'Company\MyBundle\Entity\Step#channel' that
was not configured to cascade persist operations for entity
why is it even finding new relationships from the inverse side? Here's my code:
$channel = new Channel();
$step = new Step();
$channel->addStep($step);
$em->persist($channel);
$em->flush();
Thanks!
You're right: Doctrine looks only for changes into owning side but you're wrong: owning side of your relationship is Step, not Channel.
Why is step the owning side? Because is the entity that has foreign key. Even Doctrine documentation says to you
The owning side has to use the inversedBy attribute of the OneToOne,
ManyToOne, or ManyToMany mapping declaration. The inversedBy attribute
contains the name of the association-field on the inverse-side.
Possible solutions:
Try to invert cascade operations by putting cascade={"all"} into Step entity (are you sure that all is the correct choice?)
Persist explicitly both entities:
$channel = new Channel();
$step = new Step();
$channel->addStep($step);
$em->persist($channel);
$em->persist($step);
$em->flush();
here you can read why second way provided here is fine too
You try to persist $channel, but it has Step entity inside. So in Doctrine now you have 2 entities that are queued for inserting. Then Doctrine order entities in the order where first is Step because it has channel_id foreign key (that is empty now). Doctrine try persist this entity and when it understands that channel_id is empty it sees for cascade rules for persisting. It doesn't see any cascade rules and throw you this exception.

Doctrine2 assosiation in symfony2 manytomany

i have a problem, using symfony2, doctrine
first my models and relationships:
tables:
1.company (has many employements, has many projects)
2.user (has many employements)
3.project (has one company)
4.employement (has one user, has one company)
(I know about the possibility ManyToMany between user<->company, but i go with an extra model for employement for other reasons)
The Issue: an the projects/index page, i want to show all projects, from all companies, where this user is employed, ordered by created at. As you can see a user can be employed in more companies at the same time.
In my controller i get all projects like this:
$projects = $this->getDoctrine()
->getRepository('AcmeDemoBundle:Projects')
->findAll();
I Guess the solution could be:
find employements by user
find companies by that employements
get projects by that companies...
Any Idea?
Your solution seems right, but you will probably need to create a custom repository class with joins to explicitly tell Doctrine to fetch relations (without proxy).
See Databases and Doctrine (The Symfony Book) and Doctrine Query Language — Doctrine 2 #joins
Example :
use Doctrine\ORM\EntityRepository;
class EmployementRepository extends EntityRepository
{
public function findWithJoins($user) {
$qb = $this->createQueryBuilder('e');
$qb->leftJoin('e.company', 'e')
->addSelect('e')
->where('e.user = :user')
->setParameter('user', $user);
return $qb->getQuery()->getResults();
}
}

Doctrine one-to-many situation: how to easily fetch related entities

To simplify, two entities are defined: User and Comment. User can post many comments and every comment has only one user assigned, thus Comment entity has:
/**
* #var \Frontuser
*
* #ORM\ManyToOne(targetEntity="Frontuser")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ownerUserID", referencedColumnName="id")
* })
*/
private $owneruserid;
However, when in action:
$orm = $this->getDoctrine()->getManager();
$repo = $orm->getRepository('CompDBBundle:Comment');
$repo->findBy(array('owneruserid' => $uid);
Error occured, that there's no such field like owneruserid.
How can I fetch all the user's comments then? The same happens to similar relations in my DB - looks likes you cannot run find() with foreign keys as parameters. I believe a function $user->getComments() should be automatically generated/recognised by Doctrine to allow efficient, quick access to related entities.
The example's simple but, what if there are more entities related to my User in the same way? Do I have to declare repositories for each and try to fetch them by it's owneruserid foreign keys?
Using doctrine, when you define a related entity it's type is the entity class (in this case FrontUser). Therefore firstly your related entity variable name is misleading. It should be e.g.
private $ownerUser;
Then, in order to do a findBy on a related entity field you must supply an entity instance e.g.
$orm = $this->getDoctrine()->getManager();
$userRepo = $orm->getRepository('CompDBBundle:FrontUser');
$user = $userRepo->findById($uid);
$commentRepo = $orm->getRepository('CompDBBundle:Comment');
$userComments = $commentRepo->findByOwnerUser($user);
If you don't have or want to retrieve the user entity you could use a DQL query with the 'uid' as a parameter instead.

Symfony2.1 Circular references

I'm wondering how to avoid having a circular reference in my symfony2.1 application.
I have an entity like
customer (
name
addresses -- OneToMany
currentAddress -- OneToOne )
and
address (
street
customer -- ManyToOne )
Now my fixtures won't load because it can't delete the customer because of the foreign key.
For performances' sake I would like to avoid having to add a getCurrentAddress() method on customer which would select in the addresses table.
Does anybody have a solution for that?
Adding a getCurrentAddress() isn't such a performance issue.
This way, I'll avoid the circular reference and all the issues that come along with it.
In my situation, using an order by date in the doctrine annotation was enough:
// on customer entity :
/** #ORM\OrderBy({"datemodified" = "DESC"}) */
private $addresses
public function getCurrentAddress()
{
return $this->addresses[0];
}

Resources