简体   繁体   English

重命名域类,常规和grails逆向工程

[英]rename domain class, groovy and grails reverse engineering

How do a rename a domain class while reverse engineering or after reverse engineering. 在逆向工程时或逆向工程后如何重命名域类。

i generated class using reverse engineering in Groovy and Grails. 我在Groovy和Grails中使用逆向工程生成了类。

the domain class name was AgentTable. 域名类名称为AgentTable。 I want to rename it as Agent. 我想将其重命名为Agent。 When i renamed the domain class using IntelliJ (right click - refactor - rename), it renamed the AgentTable to Agent whereever it was used. 当我使用IntelliJ重命名域类(右键单击-重构-重命名)时,无论使用什么地方,它都将AgentTable重命名为Agent。 but when i start the server (run the app), giving error "nested exception is org.hibernate.HibernateException: Missing table: agent" 但是当我启动服务器(运行应用程序)时,出现错误“嵌套的异常是org.hibernate.HibernateException:缺少表:代理”

I have to do this for few domain class. 我必须为几个域类执行此操作。 is it anyway i can give an alternative name while reverse engineering the domain classes. 无论如何,我可以在反向工程领域类时给一个替代名称。

or after domain class was created how do i rename it without this error. 或在创建域类之后,如何重命名它而不会出现此错误。

Look into your database the name of the table it created for the agent. 在数据库中查找它为代理创建的表的名称。 Once you know the name of the table add the following in your new domain 知道表的名称后,在新域中添加以下内容

static mapping = {
    table "table-name-here"
}

While it works I would not recommend @elixir 's approach. 虽然有效,但我不建议使用@elixir的方法。

In my opinion the mapping is not supposed to be used for renames. 我认为该映射不应用于重命名。 This is also how I understand the official documentation . 这也是我对官方文档的理解。

In the example they use it to map Person onto the 'people' table, not because of a rename but because of a semantic reason. 在该示例中,他们使用它来将Person映射到“ people”表,这不是因为重命名,而是因为语义上的原因。 Tables are typically named after the plural form. 表通常以复数形式命名。 Here is a nice answer on another question regarding this. 是关于这个问题的另一个很好的答案。 In the project I am working on the domain object 'User' is mapped to the table 'users'. 在项目中,我正在将域对象“用户”映射到表“用户”。 You can not use the table name 'user' as it is an SQL statement. 您不能使用表名“ user”,因为它是一条SQL语句。


Assumptions and clarifications: 假设和澄清:

In my experience Grails maps the domain name to the table name after these rules (example domain name 'MyExampleDomain': 根据我的经验,Grails遵循以下规则将域名映射到表名(示例域名“ MyExampleDomain”:

  • separate the domain name by capital letters (My Example Domain) 用大写字母分隔域名(我的示例域)

  • lower case all (my example domain) 小写全部(我的示例域)

  • replace spaces with underlines (my_example_domain) 用下划线替换空格(my_example_domain)

Following this your Domain Class 'AgentTable' has a table 'agent_table' in your respective database. 之后,您的域类“ AgentTable”在您各自的数据库中就有一个表“ agent_table”。 After your rename Grails even tells you what it wants: 重命名后,Grails甚至会告诉您它想要什么:

nested exception is org.hibernate.HibernateException: Missing table: agent 嵌套的异常是org.hibernate.HibernateException: 缺少表:代理

It wants to look up values in a table called 'agent' but it can not find it. 它想在名为“ agent”的表中查找值,但找不到它。 The refactor function of IntelliJ does not rename the functions, so it will miss out on the database. IntelliJ的重构功能不会重命名功能,因此它将在数据库上丢失。

Luckily we know exactly what values it wants - the values previously found in 'agent_table'. 幸运的是,我们确切知道它需要什么值-先前在'agent_table'中找到的值。

So why create this confusion with remapping domains and table names when we could just rename the table and be done with it? 那么,当我们可以重命名表并完成该操作时,为什么还要通过重新映射域和表名来造成这种混乱呢?


The solution: 解决方案:

Execute an SQL script like this on your database: 在数据库上执行这样的SQL脚本:

ALTER TABLE <old_domain_name> RENAME TO <new_domain_name>;

The names are of course in their "table-form". 名称当然是以其“表格形式”。

This simply renames your table to match the expected format in Grails. 这只是重命名您的表以匹配Grails中的预期格式。 When restarting everything should be fine. 重新启动时,一切都应该没问题。

However you do not need to use rename. 但是,您不需要使用重命名。 You could also create a whole new table, build it the way the domain objects wants it to be and then migrate the data. 您还可以创建一个全新的表,以域对象希望的方式构建它,然后迁移数据。 See section 'Problems with this approach' for information on when to use what. 有关何时使用什么的信息,请参见“此方法的问题”部分。


Problems with this approach: 这种方法的问题:

As always, tinkering with information a program depends on (and even generated itself) will often have some dire consequences if you aren't careful. 与往常一样,如果您不小心,修改程序所依赖的信息(甚至生成自身的信息)通常会带来可怕的后果。

For example we have to pay attention to keys. 例如,我们必须注意按键。 If your domain object has a relation to other objects it will hold them in the table via foreign keys. 如果您的域对象与其他对象有关系,它将通过外键将它们保存在表中。 Depending on how you chose to migrate the information in the table you might have deleted these foreign keys connections. 根据您选择迁移表中信息的方式,您可能已删除了这些外键连接。 You will have to add them via a separate SQL statement. 您将必须通过单独的SQL语句添加它们。 When you choose to recreate the table this will happen for sure. 当您选择重新创建表时,这肯定会发生。 Renaming it should keep the keys. 重命名它应该保留密钥。

Another one are column names. 另一个是列名。 If you choose to rename attributes you will also have to rename the columns via SQL. 如果选择重命名属性,则还必须通过SQL重命名列。 You will also have to remember the foreign keys other tables might have on the table you are renaming. 您还必须记住其他表在您重命名的表上可能具有的外键。 RENAME did this automatically for me, but you should double check. RENAME会自动为我执行此操作,但您应仔细检查。


Why you should still stick with this approach: 为什么仍要坚持这种方法:

Remapping domain objects to the tables with old names is bound to create code smell and confusion. 将域对象重新映射到具有旧名称的表势必会造成代码异味和混乱。 Do you really want to remember these mappings in your head? 您是否真的想记住这些映射? And more importantly: do you really expect other people to have to work with this? 更重要的是:您真的希望其他人必须为此工作吗?

The best case is if people can't even tell if this object has ever had a different name and changing the database is the best way I know to achieve this. 最好的情况是,如果人们什至不知道该对象是否曾经有过不同的名称,而更改数据库是我知道的最好方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM