Pregunta

¿Puede alguien darme un ejemplo de un mapeo de clave primaria @OneToOne unidireccional en Hibernate? He probado numerosas combinaciones, y hasta ahora lo mejor que he conseguido es esto:

@Entity
@Table(name = "paper_cheque_stop_metadata")
@org.hibernate.annotations.Entity(mutable = false)
public class PaperChequeStopMetadata implements Serializable, SecurityEventAware {

private static final long serialVersionUID = 1L;

@Id
@JoinColumn(name = "paper_cheque_id")
@OneToOne(cascade = {}, fetch = FetchType.EAGER, optional = false, targetEntity = PaperCheque.class)
private PaperCheque paperCheque;
}

Cada vez que Hibernate intenta generar automáticamente el esquema para la asignación anterior, intenta crear la clave primaria como un blob, en lugar de un largo, que es el tipo de identificación de PaperCheque. ¿Alguien puede ayudarme? Si no puedo obtener una solución exacta, algo cercano funcionaría, pero agradecería cualquier respuesta.

¿Fue útil?

Solución

¿Su intención es tener una relación 1-1 entre PaperChequeStopMetaData y PaperCheque? Si es así, no puede definir la instancia de PaperCheque como el @Id de PaperChequeStopMetaData, debe definir una columna @Id separada en PaperChequeStopMetaData.

Otros consejos

Guardé esta discusión cuando implementé un par de asignaciones @OneToOne , Espero que también pueda serle útil, pero no dejamos que Hibernate cree la base de datos para nosotros.

Tenga en cuenta la anotación GenericGenerator.

De todos modos, tengo este código funcionando:

@Entity
@Table(name = "message")
public class Message implements java.io.Serializable
{
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "message_id")
    public MessageContent getMessageContent()
    {
        return messageContent;
    }
}

@Entity
@Table(name = "message_content")
@GenericGenerator(name = "MessageContent", strategy = "foreign",
    parameters =
    {
      @org.hibernate.annotations.Parameter
      (
        name = "property", value = "message"
      )
    }
)
public class MessageContent implements java.io.Serializable
{
    @Id
    @Column(name = "message_id", unique = true, nullable = false)
    // See http://forum.hibernate.org/viewtopic.php?p=2381079
    @GeneratedValue(generator = "MessageContent")
    public Integer getMessageId()
    {
            return this.messageId;
    }
}

Gracias a ambos por sus respuestas. Seguí experimentando, y esto es lo que conseguí trabajando:

@Entity
@Table(name = "paper_cheque_stop_metadata")
@org.hibernate.annotations.Entity(mutable = false)
public class PaperChequeStopMetadata implements Serializable, SecurityEventAware {

private static final long serialVersionUID = 1L;

@SuppressWarnings("unused")
@Id
@Column(name = "paper_cheque_id")
@AccessType("property")
private long    id;

@OneToOne(cascade = {}, fetch = FetchType.EAGER, optional = false, targetEntity = PaperCheque.class)
@PrimaryKeyJoinColumn(name = "paper_cheque_id")
@JoinColumn(name = "paper_cheque_id", insertable = true)
@NotNull
private PaperCheque paperCheque;

@XmlAttribute(namespace = XMLNS, name = "paper-cheque-id", required = true)
public final long getId() {
    return this.paperCheque.getId();
}

public final void setId(long id) {
    //this.id = id;
    //NOOP, this is essentially a pseudo-property
}
}

Esto es, por supuesto, un truco desagradable, pero me da todo lo que quería. Los accesos de propiedad paperCheque son normales (no se muestran). Me he encontrado con este tipo de problema de mapeo unidireccional OneToOne antes y me decidí por soluciones mucho peores, pero esta vez decidí que iba a resolver, así que seguí hackeando. Una vez más, gracias a ambos por sus respuestas, es muy apreciado.

Simplemente actualizo esta pregunta para futuras vistas.

Cuando se hizo esta pregunta, creo que no había una solución adecuada para este problema. Pero desde JPA 2.0 puede usar @MapsId para resolver este problema.

Referencia con la explicación adecuada: https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/

Debe mantenerse alejado del mapeo OneToOne de hibernate, es muy peligroso. ver http://opensource.atlassian.com/projects/hibernate/browse/HHH -2128

es mejor usar las asignaciones ManyToOne.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top