JPA hibernuje relacje jeden do jednego

Mam relację jeden do jednego, ale hibernatetool narzeka podczas generowania schematu. Oto przykład, który pokazuje problem:

@Entity
public class Person {
    @Id
    public int id;

    @OneToOne
    public OtherInfo otherInfo;

    rest of attributes ...
}

Osoba ma relację jeden do jednego z OtherInfo:

@Entity
public class OtherInfo {
    @Id
    @OneToOne(mappedBy="otherInfo")
    public Person person;

    rest of attributes ...
}

Osoba jest właścicielem strony OtherInfo. OtherInfo jest własnością strony, więc osoba używa mappedBy, aby podać nazwę atrybutu "otherInfo" osobiście.

Podczas generowania schematu bazy danych za pomocą hibernatetool pojawia się następujący błąd:

org.hibernate.MappingException: Could not determine type for: Person, at table: OtherInfo, for columns: [org.hibernate.mapping.Column(person)]
        at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:292)
        at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:175)
        at org.hibernate.cfg.Configuration.iterateGenerators(Configuration.java:743)
        at org.hibernate.cfg.Configuration.generateDropSchemaScript(Configuration.java:854)
        at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:128)
        ...
Wiesz dlaczego? Czy Ja robienie czegoś złego, czy to hibernate bug?
Author: Steve Kuo, 2009-04-25

7 answers

JPA nie pozwala na @Id adnotację na OneToOne lub ManyToOne mapowanie. To, co próbujesz zrobić, to skojarzenie jednego do jednego podmiotu ze współdzielonym kluczem głównym. Najprostszym przypadkiem jest jednokierunkowy jeden do jednego z kluczem współdzielonym:

@Entity
public class Person {
    @Id
    private int id;

    @OneToOne
    @PrimaryKeyJoinColumn
    private OtherInfo otherInfo;

    rest of attributes ...
}

Głównym problemem jest to, że JPA nie zapewnia wsparcia dla współdzielonego generowania klucza podstawowego w jednostce OtherInfo. Klasyczna książka Java Persistence with Hibernate autorstwa Bauera i Kinga daje następujące rozwiązanie problemu przy użyciu rozszerzenia Hibernate:

@Entity
public class OtherInfo {
    @Id @GeneratedValue(generator = "customForeignGenerator")
    @org.hibernate.annotations.GenericGenerator(
        name = "customForeignGenerator",
        strategy = "foreign",
        parameters = @Parameter(name = "property", value = "person")
    )
    private Long id;

    @OneToOne(mappedBy="otherInfo")
    @PrimaryKeyJoinColumn
    public Person person;

    rest of attributes ...
}

Zobacz też tutaj .

 85
Author: topchef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-07 09:28:12

To powinno działać za pomocą adnotacji JPA 2.0 @ MapsId zamiast GenericGenerator Hibernate:

@Entity
public class Person {

    @Id
    @GeneratedValue
    public int id;

    @OneToOne
    @PrimaryKeyJoinColumn
    public OtherInfo otherInfo;

    rest of attributes ...
}

@Entity
public class OtherInfo {

    @Id
    public int id;

    @MapsId
    @OneToOne
    @JoinColumn(name="id")
    public Person person;

    rest of attributes ...
}

Więcej szczegółów na ten temat w dokumentacji Hibernate 4.1 w sekcji 5.1.2.2.7.

 23
Author: Mariusz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-27 10:48:17

Wystarczy dodać @JoinColumn(name="column_name") do relacji host Entity . column_name to nazwa kolumny bazy danych w tabeli person.

@Entity
public class Person {
    @Id
    public int id;

    @OneToOne
    @JoinColumn(name="other_info")
    public OtherInfo otherInfo;

    rest of attributes ...
}

Osoba ma relację jeden do jednego z OtherInfo: mappedBy= "var_name" var_name jest nazwą zmiennej dla inherinfo w klasie Person.

@Entity
public class OtherInfo {
    @Id
    @OneToOne(mappedBy="otherInfo")
    public Person person;

    rest of attributes ...
}
 10
Author: Igor Sadovnikov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-13 14:38:48

Myślę, że nadal potrzebujesz podstawowej właściwości klucza w klasie OtherInfo.

@Entity
public class OtherInfo {
    @Id
    public int id;

    @OneToOne(mappedBy="otherInfo")
    public Person person;

    rest of attributes ...
}

Może być również konieczne dodanie adnotacji @PrimaryKeyJoinColumn po drugiej stronie mapowania. Wiem, że Hibernate używa tego domyślnie. Ale wtedy nie użyłem adnotacji JPA, które wydają się wymagać, aby określić, jak Stowarzyszenie wokrs.

 4
Author: waxwing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-25 06:12:36

Mam lepszy sposób na to:

@Entity
public class Person {

    @OneToOne(cascade={javax.persistence.CascadeType.ALL})
    @JoinColumn(name = "`Id_OtherInfo`")
    public OtherInfo getOtherInfo() {
      return otherInfo;
    }

}

To wszystko

 2
Author: Vodo-Siosk Baas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-04 18:43:06

Nie jestem pewien, czy możesz użyć relacji jako Id / PrimaryKey w Hibernate.

 1
Author: razenha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-24 21:55:25

Spróbuj tego

@Entity

@Table(name="tblperson")

public class Person {

public int id;

public OtherInfo otherInfo;
@Id //Here Id is autogenerated
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}

@OneToOne(cascade = CascadeType.ALL,targetEntity=OtherInfo.class)
@JoinColumn(name="otherInfo_id") //there should be a column otherInfo_id in Person
public OtherInfo getOtherInfo() {
    return otherInfo;
}
public void setOtherInfo(OtherInfo otherInfo) {
    this.otherInfo= otherInfo;
}
rest of attributes ...
}


@Entity

@Table(name="tblotherInfo")

public class OtherInfo {

private int id;

private Person person;

@Id

@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}

  @OneToOne(mappedBy="OtherInfo",targetEntity=Person.class)   
public College getPerson() {
    return person;
}
public void setPerson(Person person) {
    this.person = person;
}    
 rest of attributes ...
}
 1
Author: Jugal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 12:09:14