Reputation: 1583
I have been trying to solve this for whole day but no luck! Also i tried to read most of the tutorials on the net but as you all know they all are full of useless examples that do not reflect what you need in the real world.
So here is my situation:
The database:
table: vehicles(vehicleId, brand, model, devYear, regNumber) <-- vehicleId is the PrimaryKey
table: extras(vehicleId, allowSmoke, allowFood, allowDrinks, airConditioner) <-- vehicleId is a PK and a FK.
The point is that if i have a class Vehicle and a class TravelExtras which are mapped to the database i want the Vehicle class to have an attribute TravelExtras travelExtras and get and set methods.
Unfortunatelly no matter what i tried when i try to persist the object in the databse i get various errors.
Here is an illustration:
EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "NaStopPU" );
EntityManager entitymanager = emfactory.createEntityManager( );
entitymanager.getTransaction( ).begin( );
TravelExtra travelExtra = new TravelExtra();
entitymanager.persist(travelExtra);
Vehicle vehicle = new Vehicle(2L, "10152487958556242", "Mazda", "626", "334343", 2005, 4);
vehicle.setTravelExtra(travelExtra);
entitymanager.persist(vehicle);
entitymanager.getTransaction().commit();
entitymanager.close( );
emfactory.close( );
Any one knows what kind of annotations to use for this One to one case ?
Upvotes: 22
Views: 47729
Reputation: 637
I know this is very old qs, but for completeness of your case you can just have (jpa 2.0)
@Entity
@Data
public class Vehicle implements Serializable{
@Id
@GeneratedValue
private long vehicleId;
.. //other props
}
@Entity
@Data
public class VehicleExtras implements Serializable{
@Id
@OneToOne (cascade = CASCADE.ALL)
@MapsId
@JoinColumn(name ="vehicleId")
private Vehicle vehicle;
@Column
private boolean allowSmoke;
..// other props.
}
should share same pk/fk for VehicleExtra table
Upvotes: 10
Reputation: 925
Why don't you use an @Embedded
object? When using an embedded object, you get
the logical separation you desire in your code and keep your database compliant with Entity-Relational Normalization rules.
It's weird to think on a One-to-One relationship, because even though JPA/Hibernate allows it, all data should be stored in the same table, making you model simpler, while also simplifying queries and increasing database performance by removing the need for a Join operation.
When using Embedded objects you don't have to worry about mapping IDs and bizarre relations, since your ORM is capable of understanding that your just making a code separation, instead of demanding an actual relation of One-to-One between tables.
class Vehicle {
@Id
@Column(name = "ID")
private long vehicleId;
@Column(name = "BRAND")
private String brand;
@Column(name = "MODEL")
private String model;
@Column(name = "DEV_YEAR")
private int devYear;
@Column(name = "REG_NUMBER")
private int regNumber;
@Embedded
private TravelExtra extras;
// Constructor, getters and setters...
}
.
@Embeddable
class TravelExtras {
@Column(name = "ALLOW_SMOKE")
private boolean allowSmoke;
@Column(name = "ALLOW_FOOD")
private boolean allowFood;
@Column(name = "ALLOW_DRINKS")
private boolean allowDrinks;
@Column(name = "AIR_CONDITIONER")
private boolean airConditioner;
// Default Constructor, getters and setters...
}
Upvotes: 4
Reputation: 1430
The Java Persistence wikibook has a section called Primary Keys through OneToOne and ManyToOne Relationships which seems to indicate that what you want is possible.
If I'm reading it right, for your case, it would look something like:
class Vehicle {
@Id
@Column(name = "EXTRAS_ID")
private long extrasId;
@OneToOne(mappedBy="vehicle", cascade=CascadeType.ALL)
private TravelExtra extras;
}
class TravelExtras {
@Id
@Column(name = "VEHICLE_ID")
private long vehicleId;
@OneToOne
@PrimaryKeyJoinColumn(name="VEHICLE_ID", referencedColumnName="EXTRAS_ID")
private Vehicle vehicle;
public TravelExtras(Vehicle vehicle) {
this.vehicleId = vehicle.getId();
this.vehicle = vehicle;
}
}
Note that one of your entities will need to make sure it has the same id as the other, which is accomplished in the example by the TravelExtras constructor requiring the Vehicle it is bound to.
Upvotes: 29
Reputation: 509
You can map your classes for example with Netbeans. It will generate annotations. The problem could be your dao layer. You have to persist objects in correct way. For example can't save travelExtra without Vehicle. Also be aware of owning side.
Upvotes: 0