2013-05-16 55 views
0

「用戶」實體是「Car」的一對多bidir關係。 「Car」實體是「CarPhoto」實體(它是「Photo」實體的繼承)的一對多比價關係。 「Car」實體與「CarPhoto」也有一對一的關係。同一物體上的一對多和一對一

因此,CarPhotos是照片給一輛汽車,汽車還指出這些照片中的任何一張應該是封面照片(想像一張照片顯示在專輯正面的專輯)。

設置封面照片時會出現問題。

請看我下面的代碼和錯誤消息:

@Entity 
public class User implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "USERS_SEQ") 
    @TableGenerator(name = "USERS_SEQ", table = "SEQUENCE", pkColumnName = "SEQ_NAME", pkColumnValue = "USERS_SEQ", valueColumnName = "SEQ_COUNT", allocationSize = 1) 
    @Column(nullable = false) 
    private long id; 

    @OneToMany(mappedBy = "user", cascade = { CascadeType.ALL }, orphanRemoval = true, fetch = FetchType.LAZY) 
    private Set<Car> cars; 

    //... 
} 

@Entity 
public class Car { 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "CARS_SEQ") 
    @TableGenerator(name = "CARS_SEQ", table = "SEQUENCE", pkColumnName = "SEQ_NAME", pkColumnValue = "CARS_SEQ", valueColumnName = "SEQ_COUNT", allocationSize = 1) 
    @Column(nullable = false) 
    private long id; 

    @OneToMany(mappedBy = "car", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true) 
    private Set<CarPhoto> photos; 

    // coverPhoto shall be NULL or a object in the Set<CarPhoto> photos 
    @OneToOne 
    @JoinColumn(name = "COVER_PHOTO", referencedColumnName = "ID") 
    private CarPhoto coverPhoto; 

    //... 

} 

@Entity 
@DiscriminatorValue("C") 
public class CarPhoto extends Photo { 

    @ManyToOne(cascade = { CascadeType.DETACH }) 
    @JoinColumn(name = "CARID", nullable = false) 
    @NotNull 
    private Car car; 

    //... 
} 

@Entity 
@Inheritance 
@DiscriminatorColumn(name = "DESCRIMINATOR") 
public abstract class Photo { 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "PHOTOS_SEQ") 
    @TableGenerator(name = "PHOTOS_SEQ", table = "SEQUENCE", pkColumnName = "SEQ_NAME", pkColumnValue = "PHOTOS_SEQ", valueColumnName = "SEQ_COUNT", allocationSize = 50) 
    @Column(nullable = false) 
    private long id; 

    //... 
} 

@Test 
public void testCarAddCarPhotos() throws Exception { 

    User user = dg.getTestUser(); // Get a user object 
    Car car = dg.getTestCar(); // Get a car object 
    CarPhoto photo = dg.getTestCarPhoto(); // Get a car photo object 

    user.addToCars(car); // Add car to user cars list 
    car.setUser(user); // ^^^ To keep bi-directional relationship^^^ 
    photo.setCar(car); // Add car as owner to this photo  
    car.addToPhotos(photo); // ^^^ To keep bi-directional relationship^^^  

    em.persist(user); 
    em.flush(); 
    em.clear(); 

    // This tests works perfectly, the user has a car, and the car has a photo 
} 

@Test 
public void testCarAddCarPhotosAddCoverPhoto() throws Exception { 

    User user = dg.getTestUser(); // Get a user object 
    Car car = dg.getTestCar(); // Get a car object 
    CarPhoto photo = dg.getTestCarPhoto(); // Get a car photo object 

    user.addToCars(car); // Add car to user cars list 
    car.setUser(user); // ^^^ To keep bi-directional relationship^^^ 
    photo.setCar(car); // Add car as owner to this photo  
    car.addToPhotos(photo); // ^^^ To keep bi-directional relationship^^^  

    // NOW TEST TO A THE COVERPHOTO 
    car.setCoverPhoto(photo); 

    em.persist(user); 
    em.flush(); 

    // ERROR: 
// javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DatabaseException 
// Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`vehicledb_test`.`PHO 
// TOS`, CONSTRAINT `FK_PHOTOS_CARID` FOREIGN KEY (`CARID`) REFERENCES `CARS` (`ID`)) 
// Error Code: 1452 
// Call: INSERT INTO PHOTOS (ID, DESCRIPTION, FILENAME, TITLE, UPLOADTIME, CARID, DESCRIMINATOR) VALUES (?, ?, ?, ?, ?, ?, ?) 
//   bind => [1, jequejnnzkxhzahaimg, rabbit, computer, 2013-05-16 21:59:42.524, 3, C] 
// Query: WriteObjectQuery(Photo [id=1, description=jequejnnzkxhzahaimg, fileName=rabbit, title=computer, uploadTime=Thu May 16 21:59:42 CEST 2013]) 
//   at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:804) 
//   at se.while_se.service.jpa.UserRepositoryTest.testModifyUserRemoveCarWithPhoto(UserRepositoryTest.java:251) 
//   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
//   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
//   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
//   at java.lang.reflect.Method.invoke(Method.java:601) 
//   at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
//   at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
//   at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
//   at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
//   at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
//   at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 
//   at org.junit.rules.TestWatchman$1.evaluate(TestWatchman.java:48) 
//   at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 
//   at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 
//   at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
//   at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
//   at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
//   at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
//   at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
//   at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
//   at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
//   at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 
//   at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
//   at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35) 
//   at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:146) 
//   at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97) 
//   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
//   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
//   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
//   at java.lang.reflect.Method.invoke(Method.java:601) 
//   at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103) 
//   at $Proxy0.invoke(Unknown Source) 
//   at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:145) 
//   at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:87) 
//   at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69) 
// Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DatabaseException 


    em.clear(); 

    // This test does not works =(
} 

附加信息:我正在運行的EclipseLink 2.4.0,MySQL的連接器的Java 5.1.20和Java 7

你能看問題在哪裏?請幫我,我有這個奮鬥了幾天了=(((

最好的問候,卡爾

回答

3

問題是由循環引用引起的,我想。照片有一個引用(外鍵)來它的車和汽車也有其封面照片的參考,所以EclipseLink似乎首先插入照片,但由於汽車還沒有插入,插入失敗。

我會簡單地堅持並刷新用戶(並且因此它的汽車和它的照片),並且然後僅設置照片作爲汽車的封面照片:

user.addToCars(car); // Add car to user cars list 
car.setUser(user); // ^^^ To keep bi-directional relationship^^^ 
photo.setCar(car); // Add car as owner to this photo  
car.addToPhotos(photo); // ^^^ To keep bi-directional relationship^^^  

em.persist(user); 
em.flush(); 

// NOW TEST TO A THE COVERPHOTO 
car.setCoverPhoto(photo); 

這種循環引用通常是一個糟糕的主意。在這種情況下,封面照片至少可以爲空。如果不是這種情況,則無法強制執行其中一個外鍵約束,或者其中一個必須延遲。

另一種解決方案是,如果沒有太多照片,將其中一個標記爲使用布爾值的封面照片。

+0

謝謝JB!這兩種解決方案都可行但是,我正在尋找布爾替代方法=) – kungcc

相關問題