書き方 - hibernate 複数db




多対多関連テーブルを余分の列にマッピングする (2)

私のデータベースには3つのテーブルがあります。ユーザとサービスのエンティティは多対多の関係を持ち、SERVICE_USERテーブルと次のように結合されています。

USERS - SERVICE_USER - サービス

SERVICE_USER表には追加のBLOCKED列が含まれています。

そのようなマッピングを実行する最良の方法は何ですか? これらは私のエンティティクラスです

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

private String userid;
private String email;

@Id
@Column(name = "USERID", unique = true, nullable = false,)
public String getUserid() {
return this.userid;
}

.... some get/set methods
}

@Entity
@Table(name = "SERVICES")
public class CmsService implements java.io.Serializable {
private String serviceCode;

@Id
@Column(name = "SERVICE_CODE", unique = true, nullable = false, length = 100)
public String getServiceCode() {
return this.serviceCode;
}
.... some additional fields and get/set methods
}

私はこの例に従っていhttp://giannigar.wordpress.com/2009/09/04/m 。http://giannigar.wordpress.com/2009/09/04/m ... using-jpa /ここにいくつかのテストコードがあります:

User user = new User();
user.setEmail("e2");
user.setUserid("ui2");
user.setPassword("p2");

CmsService service= new CmsService("cd2","name2");

List<UserService> userServiceList = new ArrayList<UserService>();

UserService userService = new UserService();
userService.setService(service);
userService.setUser(user);
userService.setBlocked(true);
service.getUserServices().add(userService);

userDAO.save(user);

問題は、hibernateがUserオブジェクトとUserServiceを持続することです。 CmsServiceオブジェクトで成功しません

私はEAGERフェッチを使用しようとしました - 進捗なし

上記のマッピングで期待している動作を達成することは可能ですか?

たぶん追加の列を使用して多数のテーブルを結合するよりエレガントな方法がありますか?


SERVICE_USERテーブルは純粋な結合テーブルではなく、追加の機能フィールド(ブロックされている)を持っているため、エンティティとしてマップし、UserとService間の多対多の関連付けを2つのOneToManyアソシエーションに分解する必要があります。 1つのサービスには多くのUserServicesがあります。

あなたは私たちに最も重要な部分を示していません。エンティティ間の関係のマッピングと初期化(問題がある部分)です。 だから私はそれがどのように見えるかをお見せします。

関係を双方向にする場合は、

class User {
    @OneToMany(mappedBy = "user")
    private Set<UserService> userServices = new HashSet<UserService>();
}

class UserService {
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name = "service_code")
    private Service service;

    @Column(name = "blocked")
    private boolean blocked;
}

class Service {
    @OneToMany(mappedBy = "service")
    private Set<UserService> userServices = new HashSet<UserService>();
}

関係にカスケードを設定しない場合、すべてのエンティティを永続化/保存する必要があります。 関係の所有側(ここではUserService側)のみを初期化する必要がありますが、両方の側が一貫していることを確認することも良い方法です。

User user = new User();
Service service = new Service();
UserService userService = new UserService();

user.addUserService(userService);
userService.setUser(user);

service.addUserService(userService);
userService.setService(service);

session.save(user);
session.save(service);
session.save(userService);

前述のように、JPAでは、余分な列を持つためには、1つのManyToMany関係ではなく、2つのOneToMany関連を使用する必要があります。 自動生成された値を持つ列を追加することもできます。 この方法では、有用であればテーブルの主キーとして機能することができます。

たとえば、余分なクラスの実装コードは次のようになります。

@Entity
@Table(name = "USER_SERVICES")
public class UserService{

    // example of auto-generated ID
    @Id
    @Column(name = "USER_SERVICES_ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long userServiceID;



    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "USER_ID")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "SERVICE_ID")
    private Service service;



    // example of extra column
    @Column(name="VISIBILITY")    
    private boolean visibility;



    public long getUserServiceID() {
        return userServiceID;
    }


    public User getUser() {
        return user;
    }

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

    public Service getService() {
        return service;
    }

    public void setService(Service service) {
        this.service = service;
    }

    public boolean getVisibility() {
        return visibility;
    }

    public void setVisibility(boolean visibility) {
        this.visibility = visibility;
    }

}




jointable