首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JPA 2删除/插入Metamodel命令

JPA 2删除/插入Metamodel命令
EN

Stack Overflow用户
提问于 2010-07-20 20:23:26
回答 1查看 1.1K关注 0票数 3

我试图使用JPA2元数据来确定从数据库中插入/删除行的顺序,这样约束就不会成为问题(稍后将在Java代码中使用)。这是使用JPA的备份/还原方法的一部分。

我的方法是:

  1. 按关系/约束的数量分组表(只考虑一对多和一对一)
  2. 具有零实例的表(如#1所示)可以在没有问题的情况下添加/删除记录
  3. 只有一个实例的表可以在相关表已经“准备好”的情况下,无需发出任何问题就可以添加/删除记录。

就绪的意思是,它的所有相关表记录都被填充,所以外键对于insert是有效的,或者没有其他表引用该表中的记录。

我确信这将是某种递归方法,但我被卡住了。任何帮助都是受欢迎的。

以下是目前为止的代码:

代码语言:javascript
复制
/**
 * Get the execution order from the EntityManager meta data model.
 *
 * This will fail if the EntityManager is not JP2 compliant
 * @param em EntityManager to get the metadata from
 * @return ArrayList containing the order to process tables
 */
protected static ArrayList<String> getProcessingOrder(EntityManager em) {
    ArrayList<String> tables = new ArrayList<String>();
    //This holds the amount of relationships and the tables with that same amount
    HashMap<Integer, ArrayList<String>> tableStats = new HashMap<Integer, ArrayList<String>>();
    //This holds the table and the tables referenced by it
    HashMap<String, ArrayList<String>> references = new HashMap<String, ArrayList<String>>();
    for (EntityType et : em.getMetamodel().getEntities()) {
        Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.FINER, et.getName());
        int amount = 0;
        Iterator<SingularAttribute> sIterator = et.getSingularAttributes().iterator();
        while (sIterator.hasNext()) {
            SingularAttribute next = sIterator.next();
            switch (next.getPersistentAttributeType()) {
                case BASIC:
                case ELEMENT_COLLECTION:
                case EMBEDDED:
                case ONE_TO_MANY:
                case ONE_TO_ONE:
                    Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.FINER,
                            "Ignoring: {0}", next.getName());
                    break;
                case MANY_TO_MANY:
                case MANY_TO_ONE:
                    Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.INFO,
                            "{3} has a {2} relationship: {0} with: {1}",
                            new Object[]{next.getName(), next.getBindableJavaType(),
                                next.getPersistentAttributeType().name(), et.getName()});
                    if (!references.containsKey(et.getName())) {
                        references.put(et.getName(), new ArrayList<String>());
                    }
                    references.get(et.getName()).add(next.getBindableJavaType().getSimpleName());
                    amount++;
                    break;
                default:
                    Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.SEVERE,
                            "Unexpected value: {0}", next.getName());
                    break;
            }
        }
        Iterator<PluralAttribute> pIterator = et.getPluralAttributes().iterator();
        while (pIterator.hasNext()) {
            PluralAttribute next = pIterator.next();
            switch (next.getPersistentAttributeType()) {
                case BASIC:
                case ELEMENT_COLLECTION:
                case EMBEDDED:
                case ONE_TO_MANY:
                case MANY_TO_MANY:
                    Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.FINER,
                            "Ignoring: {0}", next.getName());
                    break;
                case MANY_TO_ONE:
                case ONE_TO_ONE:
                    Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.INFO,
                            "{3} has a {2} relationship: {0} with: {1}",
                            new Object[]{next.getName(), next.getBindableJavaType(),
                                next.getPersistentAttributeType().name(), et.getName()});
                    if (!references.containsKey(et.getName())) {
                        references.put(et.getName(), new ArrayList<String>());
                    }
                    references.get(et.getName()).add(next.getBindableJavaType().getSimpleName());
                    amount++;
                    break;
                default:
                    Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.SEVERE,
                            "Unexpected value: {0}", next.getName());
                    break;
            }
        }
        if (!tableStats.containsKey(amount)) {
            tableStats.put(amount, new ArrayList<String>());
        }
        tableStats.get(amount).add(et.getName());
    }
    Iterator<String> iterator = references.keySet().iterator();
    while (iterator.hasNext()) {
        String next = iterator.next();
        Iterator<String> iterator1 = references.get(next).iterator();
        StringBuilder refs = new StringBuilder();
        while (iterator1.hasNext()) {
            refs.append(iterator1.next()).append("\n");
        }
        Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.FINER, "References for {0}:\n{1}", new Object[]{next, refs.toString()});
    }
    //Need to sort entities with relationships even further
    ArrayList<String> temp = new ArrayList<String>();
    for (Entry<Integer, ArrayList<String>> e : tableStats.entrySet()) {
        if (e.getKey() > 0) {
            Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.INFO, "Tables with {0} references", e.getKey());
            for (String t : e.getValue()) {
                //Check the relationships of the tables
                //Here's where I need help
                boolean ready = true;
                for (String ref : references.get(t)) {
                    if (!temp.contains(ref)) {
                        Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.INFO,
                                "{0} is not ready. Referenced table {1} is not ready yet", new Object[]{t, ref});
                        ready = false;
                    }
                }
                if (ready) {
                    Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.INFO, "{0} is ready.", t);
                    temp.add(t);
                }
            }
            //-------------------------------------------------------
        } else {
            temp.addAll(e.getValue());
        }
    }
    for (Entry<Integer, ArrayList<String>> e : tableStats.entrySet()) {
        Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.FINER,
                "Amount of relationships: {0}", e.getKey());
        StringBuilder list = new StringBuilder();
        for (String t : e.getValue()) {
            list.append(t).append("\n");
        }
        Logger.getLogger(XincoBackupManager.class.getSimpleName()).log(Level.FINER, list.toString());
    }
    tables.addAll(temp);
    return tables;
}
EN

回答 1

Stack Overflow用户

发布于 2010-07-21 12:28:11

我会用JDBC的数据库元数据来解决这个问题。

这里将使用来自java.sql.DatabaseMetadata的下列方法:

代码语言:javascript
复制
// to get the tables
getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) 

// to get the reference to the table
public ResultSet getExportedKeys(String catalog,
                                 String schema,
                                 String table)
                          throws SQLException

我在几个应用程序中都使用了这种方法,它工作得很好。

尽管这种方法不遵循JPA元模型的用法,但考虑到您的问题,我认为在JDBC元数据级别上操作更为合适。

由于可能存在循环依赖项,很难通过这样的外键依赖关系图来处理,因此您可以另外选择。

删除

  • 禁用约束
  • 删除内容
  • 启用约束

用于添加

  • 禁用约束
  • 添加内容
  • 启用约束
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3294055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档