2017-07-26 12 views
0

私は双方向の関係を構築しようとしています。私はSpring Boot JPAでSpring Boot 1.5.4.RELEASEを使って私のリポジトリを生成しています。私はお互いに関連付けられている2つのエンティティを保存しようとしますが、動作していません。私は失敗したテストステートメントについてコメントしました。JPA双方向OneToOneが動作しない

マイEntites:

ドライバ:

@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; 

} 

車:

@Entity 
@ToString 
@EqualsAndHashCode 
public class Car { 

    @Id 
    @GeneratedValue 
    private long id; 

    @Getter 
    @Setter 
    @OneToOne(mappedBy = Driver.COLUMN_CAR) 
    private Driver driver; 

} 

私はリポジトリを生成するために、春JPAを使用。

DriverRepository:

@Repository 
public interface DriverRepository extends CrudRepository<Driver, Long> { } 

CarRepositoryと:

@Repository 
public interface CarRepository extends CrudRepository<Car, Long> { } 

がテスト:最後の文が失敗した両試験で

@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())); 
    } 

} 

。何か案は?アドバイスに感謝します。

+0

あなたが '' User''と ''あなたがそれを持続する方法UserBan''、そしてどのようにあなたが戻ってDBからそれを取り出すの両方を取得/作成するコードを投稿することができますか? – Matt

+0

私のエンティティを変更し、私のリポジトリクラスと私の単体テストを投稿しました。 :)あなたが私を助けることを願っています。 –

答えて

0

投稿した内容にいくつか間違いがあります。

まず:

@OneToOne(mappedBy = Driver.COLUMN_CAR) 

mappedByは組合の反対側のJavaフィールド/プロパティの名前を期待しています。データベース列の名前ではありません。両方とも同じ名前があるので、ここでは動作します。

第二:

carRepository.findAll().forEach(eachCar -> Assert.assertNotNull(eachCar.getDriver())); 

あなたは、単一のトランザクションですべてをやっているという理由だけで失敗し、適切協会の両側を初期化に失敗しました。したがって、car.driverは、あなたが初期化したのと同じです:null。

サード:

driverRepository.findAll().forEach(eachDriver -> Assert.assertNotNull(eachDriver.getCar())); 

あなたは以前と同じミスを犯したが、さらに悪いです。ここでは、アソシエーションの片面のみを初期化しましたが、の逆アソシエーション(mappedBy属性を持つ側)を初期化しました。そのため、以前のスニペットのように、関連付けはデータベースに保存されません。

+0

最初のことは問題ではありませんでした。 理由を理解できません。カスケーディングが有効になっているので、dbに保存すると、初期化されたオブジェクトが返されます。ではなぜそれはnullですか? もう一度。カスケードとdbへの保存は問題を解決するはずですか?たぶん、関連とカスケードの仕組みの理解に大きな問題があるかもしれません。 私の問題を保存してくれるスナップを投稿できますか?だから私は間違いを見ることができますか? :)素晴らしいだろう。 –

+0

最初のことについては、もう一度お読みください。私は言った:*それは両方が同じ名前を持っているので*ここで働く。したがって、フィールドと列の名前が同じであるためにのみ機能します。期待されるのは、列名ではなく、ファイル名です。問題は、もし私がそれらをdbに保存すると、初期化されたオブジェクトが戻ってきたと思うということです*。それは間違っている。あなたが何かを保存すると、JPAはそれをそのまま永続コンテキスト(別名1次キャッシュ)に保存します。 –

関連する問題