【问题标题】:Persistency unit fails to make the relation many to many持久性单元未能建立多对多关系
【发布时间】:2012-04-07 20:32:43
【问题描述】:

好的,这是一个奇怪的问题,因为我之前有它工作过。 所以我有两个课程:游戏和开发人员。他们有一个多对多的关系。 持久性单元自动生成表 game_developer。 因此有 3 个表:game developer 和 game_developer。 当我在数据库中输入信息时。桌面游戏和开发者将正常获取值,但桌面游戏开发者将保持为空。所以这种关系是不被认可的。 此外,当我运行 webapp 时,表中的所有内容都应该被删除。开发者很好,但游戏仍然存在。

感谢任何朝着正确方向的推动。

提前谢谢你,

大卫

初始化:

try {
        gameOrganizer = (GameOrganizer) getServletContext().getAttribute("database");

        Game game = new Game("Counter Strike: source");
        Game game2 = new Game("Battlefield: bad company 3");
        Game game3 = new Game("Killing floor");

        Developer devel = new Developer("valve");
        Developer devel2 = new Developer("EA Games");
        Developer devel2b = new Developer("DICE");
        Developer devel3 = new Developer("Ubisoft");

        //The GameOrganizer is the controller between the model en the view. 
        //The view being the website.
        //So gameOrganizer.addGame(game) will persist the object to the database.

        gameOrganizer.addGame(game);
        gameOrganizer.addGame(game2);
        gameOrganizer.addGame(game3);

        gameOrganizer.addDeveloper(devel);
        gameOrganizer.addDeveloper(devel2);
        gameOrganizer.addDeveloper(devel2b);
        gameOrganizer.addDeveloper(devel3);

        game.addDeveloper(devel);
        devel.getGames().add(game);

        game2.addDeveloper(devel2);
        devel2.getGames().add(game2);

        game2.addDeveloper(devel2b);
        devel2b.getGames().add(game2);

        game3.addDeveloper(devel3);
        devel3.getGames().add(game3);

    } catch (DatabaseException ex) {
        Logger.getLogger(GameController.class.getName()).log(Level.SEVERE, null, ex);
    } catch (DomainException ex) {
        Logger.getLogger(GameController.class.getName()).log(Level.SEVERE, null, ex);
    }

游戏类:

@Entity
public class Game implements Serializable{

    private String gameNaam;
    private double prijs;
    @ManyToMany(mappedBy = "games")
    private Collection<Developer> developers = new ArrayList<Developer>();

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    public Game(){};
    .
    .
    //methods
    .
    .
  }

开发者类

@Entity
public class Developer implements Serializable  {

    private String naam;
    private String info;
    @ManyToMany
    private Collection<Game> games = new ArrayList<Game>();
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    public Developer() {
    }
    .
    .
    //methods
    .
    .
 }

持久化单元:

  <?xml version="1.0" encoding="UTF-8"?>
 <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
 <persistence-unit name="GameDatabaseSitePU" transaction-type="RESOURCE_LOCAL">
   <provider>oracle.toplink.essentials.PersistenceProvider</provider>
    <class>domainmodel.Developer</class>
    <class>domainmodel.Game</class>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="toplink.jdbc.user" value="app"/>
      <property name="toplink.jdbc.password" value="app"/>
      <property name="toplink.jdbc.url" value="jdbc:derby://localhost:1527/GameDatabase;create=true"/>
      <property name="toplink.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="toplink.ddl-generation" value="drop-and-create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

【问题讨论】:

    标签: java database jpa persistence relation


    【解决方案1】:

    无法识别关系,因为您在建立关系之前保留了对象。将对象添加到彼此的集合后,执行调用 gameOrganizer.add..()。还将级联持久化添加到开发人员的多对多关系中:

    @ManyToMany(cascade = CascadeType.PERSIST, mappedBy = "games")
    private Collection<Developer> developers = new ArrayList<Developer>();
    

    那么你只需要持久化游戏。

    【讨论】:

      【解决方案2】:

      我认为在双向多对多关系中,您需要设置双方...

      即如果你这样做了

      devel.getGames().add(game);

      你也需要这样做

      game.getDeveloper().add(devel);

      否则 JPA 不会真正看到另一边,映射表中的插入将类似于 (FK1, null),这将失败,这就是为什么你不会看到任何条目...

      我对toplink不太了解,但我认为类似

      <property name="toplink.logging.level" value="FINE"/>
      

      应该在你的日志中给你 sql 语句,这对调试这类问题有很大帮助:)

      【讨论】:

      • 嗨,我想我已经这样做了:game.addDeveloper(devel); devel.getGames().add(游戏);感谢您提供 toplink 提示。非常方便。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 2017-01-10
      • 2011-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多