2016-05-17 26 views
1

我使用EclipseLink,結果很奇怪。請考慮下面的代碼:JPA:在fied和getter上設置@Id之間的區別

此代碼:

@Entity 
@Table(name = "someTable") 
public class SomeClass{ 
    @Id// PAY ATTENTION TO THIS LINE 
    private String id; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    @Column (name = "somecol")// PAY ATTENTION TO THIS LINE 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

此代碼也可以工作:

@Entity 
@Table(name = "someTable") 
public class SomeClass{ 
    @Id// PAY ATTENTION TO THIS LINE 
    private String id; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    //@Column (name = "somecol")// PAY ATTENTION TO THIS LINE 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

此代碼也可以工作:

@Entity 
@Table(name = "someTable") 
public class SomeClass{ 

    private String id; 

    @Id// PAY ATTENTION TO THIS LINE 
    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    //@Column (name = "somecol")// PAY ATTENTION TO THIS LINE 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

此代碼沒有按」 T工作:

@Entity 
@Table(name = "someTable") 
public class SomeClass{ 

    private String id; 

    @Id // PAY ATTENTION TO THIS LINE 
    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    @Column (name = "somecol")// PAY ATTENTION TO THIS LINE 
    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

我得到以下異常:

Exception Description: Entity class [class SomeClass] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy. 
    at org.eclipse.persistence.exceptions.ValidationException.noPrimaryKeyAnnotationsFound(ValidationException.java:1425) 
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.validatePrimaryKey(EntityAccessor.java:1542) 
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processMappingAccessors(EntityAccessor.java:1249) 
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.process(EntityAccessor.java:699) 
    at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage2(MetadataProject.java:1808) 
    at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:573) 
    at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:607) 
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1948) 
    at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.callPredeploy(JPAInitializer.java:100) 
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:104) 
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:188) 
    at org.eclipse.gemini.jpa.ProviderWrapper.createEntityManagerFactory(ProviderWrapper.java:128) 
    at org.eclipse.gemini.jpa.proxy.EMFServiceProxyHandler.createEMF(EMFServiceProxyHandler.java:151) 
    at org.eclipse.gemini.jpa.proxy.EMFServiceProxyHandler.syncGetEMFAndSetIfAbsent(EMFServiceProxyHandler.java:127) 
    at org.eclipse.gemini.jpa.proxy.EMFServiceProxyHandler.invoke(EMFServiceProxyHandler.java:73) 
    at com.sun.proxy.$Proxy8.createEntityManager(Unknown Source) 

爲什麼不過去的代碼工作的?如何解釋它?

回答

3

這是因爲有像@Access這樣的東西,如果您想使用混合模式,您必須在實體和字段級別上指定它。有兩個值AccessType.PROPERTYAccesType.FIELD

默認訪問類型由您放置標識符註釋的位置(@Id)定義。如果你把它放在場上 - 這將是AccessType.FIELD,如果你把它放在吸氣 - 它將是AccessType.PROPERTY - 編輯,未由JPA定義。

如果你想註解不是字段,但屬性(字段中仍有@Id),你必須定義一個getter並將其註釋爲AccessType.PROPERTY。 (反之亦然,對於吸氣劑@Id)。

+0

我很困惑:如果放置'@ Id'的地方決定'AccessType',爲什麼它會抱怨「沒有指定主鍵」?根據你的回答,最後一個例子默認爲'AccessType.PROPERTY',而@ Id'註釋放在正確的位置不是嗎? –

+0

只是進一步的搜索給我這個答案:http://stackoverflow.com/a/13874900/395202你說什麼是一樣的**答案**,但事實證明,在**評論**部分答案,建議這樣的行爲('@ Id'決定'AccessType')不是JPA標準。 (並沒有解釋OP所面臨的行爲) –

+0

我剛剛讀過你發佈的內容。老實說,我記得有關AccessType的原因 - 僅僅是因爲我在JPA培訓中對它進行了練習(但我使用Hibernate作爲提供者)。我現在明白的是EclipseLink以不同的方式對待它。儘管如此,你是對的。我的回答沒有回答實際的問題,這就是爲什麼沒有PK的例外:)。但肯定有助於避免這些症狀。 – gmaslowski

相關問題