Reputation: 315
I try to build a bidirectional relationship. I am using Spring Boot 1.5.4.RELEASE with Spring Boot JPA to generate my repositories. I try to save two entities which are associated to each other, but it isnt working. I commented the test-statements which fails.
My Entites:
Driver:
@Entity
@ToString
@EqualsAndHashCode
public class Driver {
public static final String COLUMN_CAR = "car";
@Id
@GeneratedValue
private long id;
@Getter
@Setter
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = COLUMN_CAR)
private Car car;
}
Car:
@Entity
@ToString
@EqualsAndHashCode
public class Car {
@Id
@GeneratedValue
private long id;
@Getter
@Setter
@OneToOne(mappedBy = Driver.COLUMN_CAR)
private Driver driver;
}
I used Spring JPA to generate repositories.
DriverRepository:
@Repository
public interface DriverRepository extends CrudRepository<Driver, Long> { }
CarRepository:
@Repository
public interface CarRepository extends CrudRepository<Car, Long> { }
Test:
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class StackoverflowTest {
@Autowired
private DriverRepository driverRepository;
@Autowired
private CarRepository carRepository;
@Test
public void test1() {
Driver driver = driverRepository.save(new Driver());
Car car = carRepository.save(new Car());
driver.setCar(car);
driverRepository.save(driver);
/* Success, so the driver got the car */
driverRepository.findAll().forEach(eachDriver -> Assert.assertNotNull(eachDriver.getCar()));
/* Fails, so the car doesnt got the driver */
carRepository.findAll().forEach(eachCar -> Assert.assertNotNull(eachCar.getDriver()));
}
@Test
public void test2() {
Driver driver = driverRepository.save(new Driver());
Car car = carRepository.save(new Car());
car.setDriver(driver);
carRepository.save(car);
/* Success, so the car got the driver */
carRepository.findAll().forEach(eachCar -> Assert.assertNotNull(eachCar.getDriver()));
/* Fails, so the driver doesnt got the car */
driverRepository.findAll().forEach(eachDriver -> Assert.assertNotNull(eachDriver.getCar()));
}
}
In both tests the last statement fails. Any ideas? Thanks in Advice.
Upvotes: 0
Views: 894
Reputation: 691775
Several mistakes in what you posted.
First:
@OneToOne(mappedBy = Driver.COLUMN_CAR)
mappedBy
expects the name of the Java field/property on the other side of the association. Not the name of the database column. It works here because both happen to have the same name.
Second:
carRepository.findAll().forEach(eachCar -> Assert.assertNotNull(eachCar.getDriver()));
That fails simply because you're doing everything in a single transaction, and you failed to properly initialize the two sides of the association. So car.driver
is just as you initialized it: null.
Third:
driverRepository.findAll().forEach(eachDriver -> Assert.assertNotNull(eachDriver.getCar()));
You made the same mistake as before, but worse. Here, you only initialized one side of the association, but you initialized the inverse side of the association (the one which has the mappedBy
attribute). So the association won't even be saved in the database, as it would have been in your previous snippet.
Upvotes: 1