0

私が取り組んでいるプロジェクトは、いくつかの望ましくないMapperの動作に遭遇しました。オブジェクトがデータベースにすでに保存されていない限り、オブジェクトを多対多の関連付けに追加することはできないようです(具体的には、保存されていないオブジェクトを多対多の関連付けから取得することはできません)。

例として、M:N関係にある従業員と部門があります。経理とセキュリティの2つの部門をインスタンス化します。経理は従業員を救われる前に取得し、セキュリティは従業員を救われた後に取得します。

object Employee extends Employee with LongKeyedMetaMapper[Employee]
class Employee extends LongKeyedMapper[Employee] with IdPK {
  def getSingleton = Employee
  object name extends MappedString(this, 20)
  override def toString = name.get
}

object Department extends Department with LongKeyedMetaMapper[Department]
class Department extends LongKeyedMapper[Department] with ManyToMany with IdPK {
  def getSingleton = Department
  object employees extends MappedManyToMany(
    EmployeeDepartment,
    EmployeeDepartment.department,
    EmployeeDepartment.employee,
    Employee)
}

/* Many-to-Many association record */
object EmployeeDepartment extends EmployeeDepartment with LongKeyedMetaMapper[EmployeeDepartment]
class EmployeeDepartment extends LongKeyedMapper[EmployeeDepartment] with IdPK {
  def getSingleton = EmployeeDepartment

  object employee extends MappedLongForeignKey(this, Employee)
  object department extends MappedLongForeignKey(this, Department)
}

object Company extends App {
  DB.defineConnectionManager(DefaultConnectionIdentifier, myDBVendor)

  val accounting = Department.create
  val security = Department.create

  accounting.employees ++= Seq(
    Employee.create.name("Fred"),
    Employee.create.name("Steve"))

  security.employees ++= Seq(
    Employee.create.name("Dave"),
    Employee.create.name("Sonia")) map
    {_.saveMe()}

  accounting.employees.toList map println; println
  security.employees.toList map println
}

出力

フレッド
フレッド

デイブ
ソニア

!!!

経理の社員全員がフレッドになりました!問題は同様に拡大します。まだ保存されていないエンティティを10個追加するとaccounting.employees、アクセス時にFredへの参照が10個生成されます。

これはバグか、マッパーの有用性に対する深刻な制限のいずれかであるように思われます。次のいずれも含まないこの動作の回避策はありますか?

  • モデルの外部にあるデータ構造を使用して、保存する準備ができるまでエンティティと関連付けを追跡する、または
  • 作成時にエンティティを保存し、ユーザーが保存について「気が変わった」場合は削除を発行します
4

1 に答える 1

0

この明らかな不正行為の具体的な理由を見つけました。多対多の関連付けに要素を追加すると、次のアルゴリズムが呼び出されます。

「this」結合リストで「other」要素を検索します。
見つからない場合
  結合を作成して結合リストに追加
そうしないと
  参加リストに追加

こすりは検索条件にあります。ManyToMany.scala (Lift 2.4) で指定されているメソッドは、関連付け外部キー (コンストラクター パラメーター 3)の を「other」要素の主キー (また) isJoinForChildと比較します。isMappedManyToManyis

保存されていないエンティティwith IdPKはすべて id=-1 であるため、「this」結合リストの最初の要素が検索基準を満たし、重複して追加されます。

これは私の元の質問に答えます。変更することでこの動作を修正することができますisJoinForChild。このメソッドは、単にキーを比較するのではなく、次のようなことを行います。

その他の場合 > -1
  通常の比較
そうしないと
  インスタンス比較

...またはその趣旨の何か。これisJoinForChildは、特性を使用しprotectedてオーバーライドすることにより、非侵襲的に達成できるためです。isJoinForChild

于 2012-11-02T14:22:51.173 に答える