Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate One-to-one Mapping with interface.i need advice

i'm developing an application where all the pojos are exposed as interface but we map the real implementation class.we are using spring and JPA annotation.i'm about to test the one-to-one relationship and i'm having a light problem with the interface.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionContainer' defined in class path resource [META-INF/model-config.xml]:
Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'sessionFactory' defined in class path resource [META-INF/model-config.xml]:
Invocation of init method failed; nested exception is org.hibernate.AnnotationException:
@OneToOne or @ManyToOne on com.mycompany.project.subproject.model.UserAccountImpl.profile references an unknown entity: com.mycompany.project.

so before this class all the other mapped class are working as expected so i'll only post part of the applicationContext file that i named model-config.xml

<property name="hibernateProperties">
    <props>
        <prop key="hibernate.dialect">${hibernate.dialect}</prop>
        <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
        <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
        <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
    </props>
</property>
<property name="annotatedClasses">
    <list>
       ...
        <value>com.mycompany.project.subproject.model.UserProfileImpl</value>
        <value>com.mycompany.project.subproject.model.UserAccountImpl</value>
       ...
    </list>
</property>

here are the two involved class UserProfileImpl.java and UserAccountImpl.java

//UserAccountImpl Class
@Entity
@Table(name ="USER_ACCOUNT")
public class UserAccountImpl implements UserAccount {

  @Id @GeneratedValue
  @Column(name="USER_ACCOUNT_ID")
  private Long ID;

  ...

  @OneToOne
  @JoinColumn(name="USER_PROFILE_ID")
  private UserProfile profile;

  ...
}

//UserProfileImpl class
@Entity
@Table(name="USER_PROFILE")
public class UserProfileImpl implements UserProfile {

  @Id @GeneratedValue
  @Column(name="USER_PROFILE_ID")
  private Long ID;
  ....

  @OneToOne(mappedBy="profile")
  private UserAccount userAccount;
  ....
}

i'm still not very confortable with hibernate yet so i'm wondering if i should Change the UserProfile reference in UserAccountImpl to UserProfileImpl.Then again the same can happen in the UserProfileImpl for userAccount reference since it's a bidirectional navigation stuff. What's the best option that will no break the consistency of the structure? Thanks for reading this

like image 835
black sensei Avatar asked Nov 09 '09 12:11

black sensei


People also ask

Which of the following is an example of one to one mapping?

We have a lot of examples around us that demonstrate this one-to-one mapping. One person has one passport, a passport is associated with a single person.

How can you implement or mapping in Hibernate give an example?

One To Many Mapping in Hibernate. In simple terms, one to many mapping means that one row in a table can be mapped to multiple rows in another table. For example, think of a Cart system where we have another table for Items. A cart can have multiple items, so here we have one to many mapping.

What is the use of one to one mapping?

One to one function or one to one mapping states that each element of one set, say Set (A) is mapped with a unique element of another set, say, Set (B), where A and B are two different sets. It is also written as 1-1. In terms of function, it is stated as if f(x) = f(y) implies x = y, then f is one to one.


2 Answers

You have these options:

  1. You must tell Hibernate somehow which class to use for the interface UserAccount. Currently, the most simple solution is to use a concrete type instead of the interface in your UserProfileImpl.

  2. You can use @Target to specify the implementation to use (see [the docs][1]).

  3. You can map the field with a custom UserType. This allows to chose the mapping (which implementation to use for an interface) at runtime but you must write the code to copy the fields between your business objects and the DB yourself (no automatic mapping anymore).

like image 108
Aaron Digulla Avatar answered Sep 28 '22 16:09

Aaron Digulla


You could try the following:

@OneToOne(mappedBy="profile", targetEntity=UserAccountImpl.class)
private UserAccount userAccount
like image 42
dlinsin Avatar answered Sep 28 '22 15:09

dlinsin