|
Fornax-Platform
Forum |
|
View:
New views
10 Messages
—
Rating Filter:
Alert me
|
|
|
[Sculptor] how to control surrogate key nameI have a couple questions regarding Hibernate/DDL generation in Sculptor.
Is there a way I can specify what the name of the surrogate key column should be? I have to follow a standard where the name would be <table name>_ID. e.g. ADDRESS_ID instead of ID. Can I do this with Sculptor? Also, is there a way to not have a surrogate key for some tables, and use a business key instead? I know this isn't the recommended approach, but I have a couple exception cases where I'd like to do this. Thanks for Sculptor Ron |
|
|
Re: [Sculptor] how to control surrogate key nameYour first question:
It is possible to do this using the excellent AOP facilitates of oAW. Do like this: 1. Add an extension advice file in your target project, location: src/main/resources/extensions/SpecialCases.ext content: import sculptormetamodel; extension extensions::helper; extension extensions::dbhelper; around transformation::Transformation::modifyDatabaseNames(DomainObject domainObject) : ctx.proceed() -> domainObject.getIdAttribute().setDatabaseColumn(domainObject.getDatabaseName() + "_ID"); 2. In workflow.oaw in your target project you need to add the following: <component adviceTarget="modelTransformation" class="oaw.xtend.XtendAdvice"> <extensionAdvice value="extensions::SpecialCases" /> </component> That's all! However, I found a bug in the DDL generation. It uses a hardcoded ID in the foreign key constraints (CSC-224). I have fixed this, but it is not deployed yet. I will look at your second question later. /Patrik |
|
|
Re: [Sculptor] how to control surrogate key nameWow, that is so cool. I had no idea you can use AOP on the transformations. I also didn't know that this file is what adds a lot of properties to my model. Looks like I need to clean up some of my hacks elsewhere. ;)
--Polly
|
|
|
Re: [Sculptor] how to control surrogate key nameYour second question
Sculptor adds id to all persistent DomainObjects and assumes in the generation phase that an id attribute exists. I think it is tricky to support your request in a general manner, foreign keys etc, but if you have a specific exception it might be possible, but that depends on what you need. Starting point... 1. Skip id attribute in the transformation for some DomainObjects. Use AOP as I described for the first question. around transformation::Transformation::modifyIdAttribute(DomainObject domainObject) : if domainObject.name != "NoIdEntity" then ctx.proceed(); 2. Adjust generation templates. Use AOP, add AROUND advices in src/main/resources/templates/SpecialCases.xpt in your target project. «AROUND templates::Hibernate::id FOR DomainObject» «IF getIdAttribute() == null -» <id /> «ELSE -» «targetDef.proceed() » «ENDIF -» «ENDAROUND» Let me know if you need some adjustments to Sculptor to support your case. /Patrik |
|
|
Re: [Sculptor] how to control surrogate key nameThanks, I used the latest 1.5.0 snapshot code and it works great.
I'm getting up to speed on oAW/Sculptor, and had a couple more things I was trying to find how to do: - The foreign key reference columns are named based on the referred-to table (e.g. ADDRESS). Can I customize this to be the same column name as the primary key of the referred-to table (ADDRESS_ID in my example). - Is there a way I can customize the names of the CREATEDDATE, CREATEDBY, etc column names? - For entities that don't have a business key (such as address), Sculptor generates the UUID column/attribute. Is there a way I can name this <table name>_ID instead of UUID. For entities with a business key, the below works great. Thanks again --Ron
|
|
|
Re: [Sculptor] how to control surrogate key nameI don't think it is named based on the referred-to table, it is named based on the name of the reference. Otherwise it would not be possible to have several references to the same target DomainObject. Try this: Entity Person { - String name - @Address primaryAddress - @Address secondaryAddress } ValueObject Address { String street; } However, it is possible to specify the name of the database columns, as described here: http://www.fornax-platform.org/cp/display/fornax/3.+Advanced+Tutorial+%28CSC%29#3.AdvancedTutorial%28CSC%29-DatabaseNames These attributes are added on the fly by the Transformation. You can replace that transformation by using an around of the transformation extension as described earlier. It is the the extension named addAuditable that you need to replace. I think I have read somewhere that it is not possible to intercept JAVA extensions and if that is a problem you can intercept the extension named modifyAuditable instead. See Transformation.ext. You have to invoke your own Java helper class and do something similar to GenerationHelper.addAuditable, but set the databaseColumn of the attributes. createdBy.setDatabaseColumn("myCreatedDate"); If you need to change the names of the Java attributes for these it is the same first step, but you also have to replace AuditInterceptor and specify the gui.systemAttributes generator property. In your sculptor-generator.properties: framework.auditInterceptorClass=org.foo.bar.MyAuditInterceptor gui.systemAttributes=id,uuid,version,myCreatedBy,myCreatedDate,myUpdatedBy,myLastUpdated,myLastUpdatedBy Aren't you using <table name>_ID for the surrogate id (id attribute)? UUID is not the same as ID. The uuid attribute is also added by Transformation.ext. It should be possible for you to replace that in the same way as described above. addUuidAttribute or modifyUuid in Transformation.ext. |
|
|
Re: [Sculptor] how to control surrogate key nameFor the foreign key reference column name, I didn't realize you could assign those column names. Worked like a charm. To customize the auditable columns, I added the following to my SpecialCases.ext: Entity myAddAuditable(Entity entity) : addAuditable(entity) -> entity.attributes.select(a | a.name == 'createdBy').setDatabaseColumn('CREATED_BY') -> entity.attributes.select(a | a.name == 'lastUpdated').setDatabaseColumn('LAST_UPDATED_DATE') -> entity.attributes.select(a | a.name == 'lastUpdatedBy').setDatabaseColumn('LAST_UPDATED_BY') -> entity.attributes.select(a | a.name == 'createdDate').setDatabaseColumn('CREATED_DATE'); Entity addAuditable(Entity entity) : JAVA org.fornax.cartridges.sculptor.generator.util.GenerationHelper.addAuditable(sculptormetamodel.Entity); As far as the UUID attribute, I guess what I really want to do is get rid of the natural key altogether and just use the surrogate key for this particular table. I tried overriding the modifyUuid extension to not generate the UUID attribute at all via: modifyUuid(DomainObject domainObject) : null; But the UUID attribute was still generated for some reason. For now I'm keeping a natural key in this table although I don't really need it. I ran into something else which I want to check whether is a bug or working as intended... I have a persistent entity class A which has a collection of non-persistent value objects B. Class B has a reference to Class C, which IS persistent. The hibernate mapping and table for B are not generated (good), but the hibernate mapping for class A has a reference to class B, which causes an error because class B isn't a persistent entity. I didn't see a way to specify the reference from A to B should be non-persistent. Am I missing something? Ex: Entity A { - Set<@B> bs } ValueObject B { not persistent - @C c } Entity C { } |
|
|
Re: [Sculptor] how to control surrogate key nameStrange. As far as I can see it should not be generated if you skipped it in the transformation. I have changed things in this area recently to support multi levels of subclasses. Are you using latest trunk? Good observation. It is a bug. I have fixed it in trunk. I will add a jira for the record also, but right now the server is down. /Patrik |
|
|
Re: [Sculptor] how to control surrogate key nameWorks now.. I updated to the latest code, but think I may have been setting up my aspect wrong anyways. For anyone else needing to do the same, following is the code: around transformation::Transformation::modifyUuid(DomainObject domainObject) : myModifyUuid(domainObject); // Don't automatically add UUID natural key attribute myModifyUuid(DomainObject domainObject) : null; Is there somewhere we can document these types of recipes? The Wiki? |
|
|
Re: [Sculptor] how to control surrogate key nameGood. Developer's Guide is the place to document these kind of things. I have added a section about this now: http://fornax-platform.org/cp/display/fornax/7.+Developer%27s+Guide+%28CSC%29#7.Developer%27sGuide%28CSC%29-CustomizetheTransformations
I don't think you need myModifyUuid. I think you can return null instead. Correct? /Patrik
|
| Free Forum Powered by Nabble | Forum Help |