Estamos tratando de usar el modo de Hibernación con una base de datos que utiliza un mucho de claves compuestas y que ha estado causando muchos dolores de cabeza.
Desafortunadamente, no podemos cambiar el esquema por eso tenemos que hacer un montón de asignación adicional entre nuestros campos. Estamos restringidos a usar JPA 1.0 y Hibernate 3.3.

El mayor problema
que hemos tenido hasta ahora es que hacer con un uno-a-uno de la asociación entre dos entidades con una clave compuesta de 2 valores, donde las tablas tienen diferentes nombres
en estas columnas (el DB tiene una convención de nomenclatura de tener una tabla específica de prefijo en cada columna).

Cada vez que realizamos en nuestra consulta, de esta excepción:

Caused by: org.hibernate.TypeMismatchException Provided id of the wrong type for class com.business.entity.InvestorIssuerEmailEntity.  
Expected: class com.business.entity.InvestorIssuerEmailEntityPK, got class com.business.entity.InvestorIssuerEntityPK; 

Las dos clases de estas tablas, InvestorIssuerEntity y InvestorIssuerEmailEntity, tienen una opción de @OneToOne asociación
(en algunos casos InvestorIssuer no tiene ningún registro coincidente en InvestorIssuerEmail):

@IdClass(InvestorIssuerEntityPK.class)
@Table(name = "T090_INVESTOR_ISSUER")
@Entity
InvestorIssuerEntity
@Column(name = "T090_091_INVESTOR_ID", nullable = false, insertable = true, 
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T090_102_ISSUER_ID", nullable = false, insertable = true, 
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;
(other fields omitted)
@OneToOne(optional = true)
@JoinColumns(value = {
@JoinColumn(name="T090_091_INVESTOR_ID", referencedColumnName = "T284_INVESTOR_ID", nullable = false, insertable = false, updatable = false),
@JoinColumn(name = "T090_102_ISSUER_ID", referencedColumnName = "T284_ISSUER_ID", nullable = false, insertable = false, updatable = false)
})
@NotFound(action = NotFoundAction.IGNORE)
private InvestorIssuerEmailEntity investorIssuerEmail;
... 
InvestorIssuerEntityPK 
@Id
@Column(name = "T090_091_INVESTOR_ID", nullable = false, insertable = true, 
updatable = true, length = 18, precision = 0)
private Long investorId;
@Id
@Column(name = "T090_102_ISSUER_ID", nullable = false, insertable = true, 
updatable = true, length = 18, precision = 0)
private Long issuerId;
...
@IdClass(InvestorIssuerEmailEntityPK.class)
@Table(name = "T284_INVESTOR_ISSUER_EMAIL")
@Entity
InvestorIssuerEmailEntity
@Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true, 
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T284_ISSUER_ID", nullable = false, insertable = true, 
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;
...
InvestorIssuerEmailEntityPK 
@Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true, 
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T284_ISSUER_ID", nullable = false, insertable = true, 
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;  

He tratado de evitar la coincidencia de Tipo de problema mediante el uso de la misma clase que el @EmbeddableId para las dos entidades, y, a continuación, utilizando @AttributeOverrides, como este:

@Id
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "investorId",
column = @Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true, updatable = true, length = 18, precision = 0)),
@AttributeOverride(name = "issuerId",
column = @Column(name = "T284_ISSUER_ID", nullable = false, insertable = true, updatable = true, length = 18, precision = 0))
})
private InvestorIssuerId investorIssuerId;

Yo sólo hice el cambio de estas dos entidades, aunque, todavía el uso de la @IdClass enfoque para el resto de las entidades (Es un caso de utilizar sólo @IdClass O @EmbeddableId para sus entidades, no tanto?)

Que acabó siendo los otros temas como «columna Repetidos en la asignación para la entidad», así que hemos vuelto a este enfoque para ver si hay otras soluciones para esto.

¿Alguien tiene alguna solución para evitar este problema? He mirado en StackOverflow, pero no ha llegado a través de cualquier de los casos donde el compuesto de las claves que se utilizan en la asociación tienen nombres diferentes.

Nota:
Incluso después de probar la sugerencia a continuación, nos aparece este error: org.hibernate.MappingException: columna Repetidos en la asignación para la entidad: com.de negocios.entidad.InvestorIssuerEntity columna: T090_091_INVESTOR_ID (debe ser asignado con insert=»false» update=»false»)

Incluso me quitan TODAS las asociaciones de InvestorIssuerEntity y todavía tengo el mismo problema. El error sólo fue cuando me quitaron el @anotación en la Columna de la clave compuesta de la clase. Por supuesto, las consultas no funciona debido a que el investorId no estaba asignada! No entiendo donde Hibernate fue la búsqueda de la «columna Repetidos en la cartografía», puesto que ya había eliminado toda mención de T090_091_INVESTOR_ID más, excepto para la clave compuesta.

Tenemos otras asociaciones en InvestorIssuerEntity que hacer una combinación en la misma de las claves principales, pero las entidades asociadas también tienen columnas adicionales en sus claves compuestas. Una vez que usted utilice @EmbeddedId, se supone que debes usar para todas las entidades? Todavía usamos @IdClass para las demás clases. Pero entonces, ¿cómo que causan una «columna repetidos» en cualquier lugar?

2 Comentarios

  1. 5

    Parece que tengo una solución para tu caso:

    @Entity
    public class InvestorIssuerEntity {
    @EmbeddedId 
    private InvestorIssuerEntityPK investorIssuerEntityPK;
    @OneToOne(optional=true, mappedBy="investorIssuerEntity")
    private InvestorIssuerEmailEntity investorIssuerEmailEntity;
    }
    @Entity
    public class InvestorIssuerEmailEntity {
    @EmbeddedId @AttributeOverrides({
    @AttributeOverride(name="investorId", column=@Column(name="T02_INV_ID")),
    @AttributeOverride(name="issuerId", column=@Column(name="T02_ISS_ID"))
    })
    private InvestorIssuerEntityPK investorIssuerEntityPK;
    @OneToOne(optional=true) @PrimaryKeyJoinColumns({
    @PrimaryKeyJoinColumn(name="T02_ISS_ID", referencedColumnName="T01_ISS_ID"), 
    @PrimaryKeyJoinColumn(name="T02_INV_ID", referencedColumnName="T01_INV_ID")
    })
    private InvestorIssuerEntity investorIssuerEntity;
    }
    @Embeddable
    public class InvestorIssuerEntityPK implements Serializable {
    private static final long serialVersionUID = -1176248537673293674L;
    @Column(name="T01_INV_ID")
    private Long investorId;
    @Column(name="T01_ISS_ID")
    private Long issuerId;
    }

    Se genera la siguiente DDL, que parece ser lo que usted está buscando:

    create table InvestorIssuerEmailEntity (
    T02_INV_ID bigint not null,
    T02_ISS_ID bigint not null,
    primary key (T02_INV_ID, T02_ISS_ID)
    )
    create table InvestorIssuerEntity (
    T01_INV_ID bigint not null,
    T01_ISS_ID bigint not null,
    primary key (T01_INV_ID, T01_ISS_ID)
    )
    alter table InvestorIssuerEmailEntity 
    add constraint FKC2FBCC4E1E26612E 
    foreign key (T02_INV_ID, T02_ISS_ID) 
    references InvestorIssuerEntity
    • Muchas gracias partenón, voy a probar esto y ver si eso soluciona nuestro problema. InvestorIssuerEntity tiene otras asociaciones se unieron en investorId + issuerId pero sus claves compuestas también tiene una columna adicional – voy a ver si esta no tiene como resultado la «columna Repetidos en la asignación de error».
    • jeff303: Pero yo todavía tengo el problema, sin embargo. Ver mi NOTA en la edición de las preguntas anteriores. Puede alguien más puede confirmar que se ha solucionado su problema?
    • No es claro para mí, ¿cuál es su código final, así que no te puedo ayudar en la identificación de lo que está mal.
  2. 0

    Quiero mencionar un enfoque alternativo:

    • pro: Ambas entidades pueden utilizar sus propios PK clase
    • con: El 1:1 relación se manifiesta en un Conjunto con 1 entrada

    Usted puede cambiar a un @OneToMany Relación y almacén de la entidad relacionada en un Conjunto. El Set tiene 1 entrada, que puede ser descomprimido en un post-procesamiento de paso.

    @OneToMany
    @JoinColumns(value = {
    @JoinColumn(name="T090_091_INVESTOR_ID", referencedColumnName = "T284_INVESTOR_ID", nullable = false, insertable = false, updatable = false),
    @JoinColumn(name = "T090_102_ISSUER_ID", referencedColumnName = "T284_ISSUER_ID", nullable = false, insertable = false, updatable = false)
    })
    @NotFound(action = NotFoundAction.IGNORE)
    private Set<InvestorIssuerEmailEntity> investorIssuerEmails;

Dejar respuesta

Please enter your comment!
Please enter your name here