views:

650

answers:

2

Hi,

Maybe this is a stupid question but it's bugging me.

I have a bi-directional one to many relationship of Employee to Vehicles. When I persist an Employee in the database for the first time (i.e. it has no assigned ID) I also want its associated Vehicles to be persisted.

This works fine for me at the moment, except that my saved Vehicle entity is not getting the associated Employee mapped automatically, and in the database the employee_id foreign key column in the Vehicle table is null.

My question is, is it possible to have the Vehicle's employee persisted at the same time the Employee itself is being persisted? I realise that the Employee would need to be saved first, then the Vehicle saved afterwards. Can JPA do this automatically for me? Or do I have to do something like the following:

Vehicle vehicle1 = new Vehicle();
Set<Vehicle> vehicles = new HashSet<Vehicle>();
vehicles.add(vehicle1);

Employee newEmployee = new Employee("matt");
newEmployee.setVehicles(vehicles);
Employee savedEmployee = employeeDao.persistOrMerge(newEmployee);

vehicle1.setAssociatedEmployee(savedEmployee);
vehicleDao.persistOrMerge(vehicle1);

Thanks!

Edit: As requested, here's my mappings (without all the other methods etc.)

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="employee_id")
    private Long id;

    @OneToMany(mappedBy="associatedEmployee", cascade=CascadeType.ALL)
    private Set<Vehicle> vehicles;

    ...

}

@Entity 
public class Vehicle {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="vehicle_id")
    private Long id;

    @ManyToOne
    @JoinColumn(name="employee_id")
    private Employee associatedEmployee;

    ...
}

I just realised I should have had the following method defined on my Employee class:

public void addVehicle(Vehicle vehicle) {
    vehicle.setAssociatedEmployee(this);
    vehicles.add(vehicle);
}

Now the code above will look like this:

Vehicle vehicle1 = new Vehicle();

Employee newEmployee = new Employee("matt");
newEmployee.addVehicle(vehicle1);
Employee savedEmployee = employeeDao.persistOrMerge(newEmployee);

Much simpler and cleaner. Thanks for your help everyone!

+1  A: 

Hi.

One way to do that is to set the cascade option on you "One" side of relationship:

class Employee { ...

@OneToMany(cascade = {CascadeType.PERSIST}) private Set vehicles = new HashSet();

... }

by this, when you call

Employee savedEmployee = employeeDao.persistOrMerge(newEmployee);

it will save the vehicles too.

BR

Denes

Hi, thanks for the reply. I do have the cascade set where you've suggested and the vehicles do get saved. My problem is that when the vehicles are saved, I want their foreign key column employee_id to contain the id of the employee I just saved.
Annie
The foreign key is supposed to be saved in the cascade... could you send the @OneToMany and @ManyToOne annotations that you are using for checking?Best RegardsDenes
I've updated my original post to include the annotations.
Annie
Hi,The problem is because of the mappedBy attribute, which defines the owner of the relation as the Many side. That´s the way that is supposed to be in bidirecional One to Many Relationships, but it´s possible to change so the owner will be the One side as you intended.This link, section 2.2.5.3.2.1 has a sample how to do it.http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.htmlBest RegardsDenes
+2  A: 

You have to set the associatedEmployee on the Vehicle before persisting the Employee.

Employee newEmployee = new Employee("matt");
vehicle1.setAssociatedEmployee(savedEmployee);
vehicles.add(vehicle1);

newEmployee.setVehicles(vehicles);

Employee savedEmployee = employeeDao.persistOrMerge(newEmployee);
Bobby
Ooh, ok. That works. But I thought there might be a way where I don't have to explicity set the associated employee on the vehicle?
Annie
I don't think that is possible with JPA. I have also used Hibernate and there if I remember correctly that is possible.
Bobby
Thanks for pointing out the problem in my original code, I've updated it with how I'm going to solve it.
Annie
YOU RULE man...Great solution...I had this problem for days.. I have thought this solution myself but wasnt logical to me
Parhs