2

質問があります:

user と user_login を user.id -> user_login.user_id で OneToOne に結合する必要があります。

問題は、.updateObject(user) を実行すると、2 つのクエリが実行されることです。

Hibernate: ユーザー (created、modified、email、first_name、last_name) の値 (?、?、?、?、?) に挿入 Hibernate: user_login (created、modified、password、user_id) の値 (?、?、?、 ?) [2012-08-15 12:15:04,192] [エラー] [http-bio-8080-exec-1] SqlExceptionHelper [144]: 列 'user_id' を null にすることはできません

2つのオブジェクト間に参照がないように見えます。Entity User の場合は、setUserLogin メソッドに userLogin.setUser(this); という行を追加します。その作業ですが、私はこの方法が正直にエレガントだとは思いません。エンティティ構成で見逃したものはありますか?それはおそらく自動的に行われませんか?

ありがとうございました

ここに私のエンティティがあります

@Entity
@NamedQueries({ @NamedQuery(name = "user.list", query = "select u from User u") })
public class User implements java.io.Serializable {

    @Column(name = "first_name", nullable = true)
    private String firstName;   

    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name="user_id", nullable=false)
    private UserLogin userLogin;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }


    public UserLogin getUserLogin() {
        return userLogin;
    }

    public void setUserLogin(UserLogin userLogin) {
        this.userLogin = userLogin;
        //userLogin.setUser(this); THIS IS THE LINE THAT FIXES IT, BUT I DONT FIND THIS WAY ELEGANT
    }

}


@Entity
@Table(name="user_login")
public class UserLogin implements java.io.Serializable {

    @Column(name = "password", nullable = false)
    private String password;


    @OneToOne(optional = false, fetch = FetchType.LAZY) 
  private User user;


    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }   

}

JSP ファイル:

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<html>
<head>
<title>Registration Page</title>
</head>
<body>
    <form:form action="/test" commandName="user">
        <tr>
            <td>User Name :</td>
            <td><form:input path="firstName" /></td>
        </tr>
        <tr>
            <td>Password :</td>
            <td><form:input path="userLogin.password" /></td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Register"></td>
        </tr>
        </table>
    </form:form>
</body>
</html>

スプリング コントローラー:

@Controller(value = "/")
public class Test { 

  @Autowired
    UserServiceImpl userServiceImpl;

  @RequestMapping(method = RequestMethod.GET, value = "/test")
  public void test(ModelMap model) {

    model.addAttribute("user", new User());

  }

  @RequestMapping(method = RequestMethod.POST, value = "/test")
  public void test(User user) {

    userServiceImpl.update(user);    

  }
} 
4

1 に答える 1

2

いつものように、双方向の関係には所有側があります。リレーションシップの所有側は、mappedBy によって参照される属性です。userあなたの場合、UserLoginエンティティの属性は所有側です。

リレーションシップがデータベースに永続化される場合、所有側のみが参照されます。これは、user永続化できるように属性の値を設定する必要があることを意味します。メモリ内のエンティティ グラフも一貫した状態に保つには、関係の両側を設定する必要があります。

JPA 2.0仕様では、これは次の言葉で伝えられています。

管理対象エンティティ間の双方向の関係は、関係の所有側が保持する参照に基づいて永続化されます。所有側で保持されているメモリ内参照と逆側で保持されているメモリ内参照が変更された場合に、これらの参照を互いに一致させておくことは、開発者の責任です。

于 2012-08-15T18:37:21.273 に答える