Problema de mapeamento da primavera-hibernato
-
22-09-2019 - |
Pergunta
Eu tenho um aplicativo de hibernação de primavera que está falhando em mapear um objeto corretamente: basicamente eu tenho 2 objetos de domínio, um Post
e a User
. A semântica é que toda postagem possui 1 usuário correspondente.
o Post
O objeto de domínio parece aproximadamente o seguinte:
class Post {
private int pId;
private String attribute;
...
private User user;
//getters and setters here
}
Como você pode ver, Post
contém uma referência a User
. Quando eu carrego um Post
objeto, eu quero corresponder User
Objeto a ser carregado (preguiçoso - somente quando necessário).
Meu mapeamento parece o seguinte:
<class name="com...Post" table="post">
<id name="pId" column="PostId" />
<property name="attribute" column="Attribute" type="java.lang.String" />
<one-to-one name="User" fetch="join"
class="com...User"></one-to-one>
</class>
E é claro que tenho um mapeamento básico para User
configurar.
No que diz respeito ao meu esquema de mesa, tenho uma mesa chamada post
com um estrangeiro UserId
que se vincula ao user
tabela.
Eu pensei que essa configuração deveria funcionar, mas quando eu carrego uma página que força o carregamento preguiçoso do User
Objeto, noto a seguinte consulta hiberada sendo gerada:
Select ... from post this_ left outer join user user2_ on this.PostId=user2_.UserId ...
Obviamente, isso está errado: deve estar se juntando UserId
a partir de post
com UserId
a partir de user
, mas em vez disso está se juntando incorretamente PostId
a partir de post
(sua chave primária) com UserId
a partir de user
.
Alguma ideia? Obrigado!
Atualizar: Graças a algumas das postagens abaixo, percebo agora que deveria estar usando um mapeamento muitos para um em vez de um para um. Eu mudei o mapeamento sob post
para o seguinte:
<many-to-one name="User" class="com...User" column="uId"/>
Mas agora recebo um erro de tempo de execução me dizendo que não há nenhum atributo chamado uId
. Isso faz sentido, já que eu não tenho um uId
coluna no meu post
objeto de domínio (eu simplesmente tenho uma referência a um user
objeto). Agora estou realmente confuso sobre como posso me tornar hibernado para perceber que ele precisa mapear o Chave estrangeira Da tabela de postagem para a tabela de usuários. Deve adicionar explicitamente um uId
atributo ao meu post
objeto de domínio para ser um espaço reservado para a chave estrangeira?
Espero estar fazendo sentido ...
Solução
Como um usuário tem muitas postagens, sua associação é de fato um "muitos para um", não um "um a um". Deve funcionar se você mapeá -lo de acordo.
Editar: Sim, você pode mapear a propriedade Post.User na postagem com um "muitos para um" ou o usuário definido. Posts no usuário com um "um para muitos" ou ambos. Você especificou o nome da sua coluna de chave estrangeira?
Edit2: No Hibernate Speak, uma "coluna" no banco de dados é mapeada para uma "propriedade" na sua classe Java. Ou seja, o atributo da coluna contém o nome da sua coluna de chave estrangeira no banco de dados, não o nome de qualquer propriedade da sua classe Java. Se eu ler sua pergunta corretamente, você deve usar "UserID", não "UID".
Ah, e um busca = "junção" não pode ser preguiçoso, pois exige que o usuário seja buscado na mesma consulta que a postagem.
Outras dicas
Esse é o comportamento de um mapeamento individual. Eles geralmente compartilham uma chave primária. O hibernato está assumindo que a chave primária do post é a mesma chave do usuário. Esta página resume esse comportamento.
Eu suspeito que um usuário possa realmente ter mais de uma postagem. Isso faz do seu mapeamento um para muitos.