GORM setup using Gradle and Groovy - groovy

Can anyone please share the steps to setup GORM using gradle and use the same in groovy ?

GORM for Hibernate has excellent documentation
Particularly the section of Using GORM For Hibernate Outside Grails
At minimum you need:
compile "org.grails:grails-datastore-gorm-hibernate5:6.1.10.RELEASE"
runtime "com.h2database:h2:1.4.192"
runtime "org.apache.tomcat:tomcat-jdbc:8.5.0"
runtime "org.apache.tomcat.embed:tomcat-embed-logging-log4j:8.5.0"
runtime "org.slf4j:slf4j-api:1.7.10"
Entities should go under src/main/groovy
#Entity
class Person implements GormEntity<Person> {
String firstName
String lastName
static constraints = {
firstName blank:false
lastName blank:false
}
}
and then finally bootstrap the data store somewhere:
import org.grails.orm.hibernate.HibernateDatastore
Map configuration = [
'hibernate.hbm2ddl.auto':'create-drop',
'dataSource.url':'jdbc:h2:mem:myDB'
]
HibernateDatastore datastore = new HibernateDatastore( configuration, Person)

Related

Jaxb generated sources with nullable fields

I have kotlin project where I'm using Jaxb generated src files from xsd. The problem with these generated sources is that they have nullable fields but IDEA does not know about it. It can lead to bugs in production. To fix it we can add #Nullable annotation to all getters in generated srs-es.
How can we do it gracefully?
I made this solution, it works for me but maybe somebody knows better approuch?
Gradle kt task
tasks.register("nullableForXsdFields") {
group = "code generation"
description = "Add Nullable annotation to generated jaxb files"
actions.add {
val xjcFiles = fileTree("$buildDir/generated-sources/main/xjc")
xjcFiles.forEach { xjcFile ->
var content = xjcFile.readText()
Regex("(public) (\\w+|<|>|\\*) (get)").findAll(content).distinct()
.forEach { match ->
content = content.replace(
match.groups[0]!!.value,
match.groups[0]!!.value.replace("public ", "public #Nullable ")
)
}.run {
content = content.replace(
"import javax.xml.bind.annotation.XmlType;",
"import javax.xml.bind.annotation.XmlType;\nimport org.jetbrains.annotations.Nullable;"
)
}
xjcFile.writeBytes(content.toByteArray())
}
}
}
tasks.getByName("xjcGeneration").finalizedBy("nullableForXsdFields")
tasks.getByName("compileKotlin").dependsOn("nullableForXsdFields")
tasks.getByName("compileJava").dependsOn("nullableForXsdFields")
xjcGeneration - is my plugin to generate src from xsd
I faced the same problem, so I've created an extension for maven jaxb plugin
com.github.labai:labai-jsr305-jaxb-plugin.
This extension marks all generated packages as nullable by default, and then marks with #NotNull only those fields, which are mandatory by xsd scheme.
You can find more details how to use it with maven in github
https://github.com/labai/labai-jsr305

Cassandra List<UDT> not getting deserialized using datastax java driver 4.0.0

I am currently working on a new project and chose Cassandra as our data store.
I have a use case where I store prices for material and to accomplish it I created list of User-Defined Types (UDTs). But unfortunately, while deserialization using datastax driver. After queries for the required data, I found that the list object is null while in the database there is value for it. Is it a current limitation of Cassandra java driver or am I missing something?
This is how my simplified Entity (table) looks like:
#PrimaryKeyColumn(name = "tenant_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private long tenantId;
#PrimaryKeyColumn(name = "item_id", ordinal = 1, type = PrimaryKeyType.CLUSTERED)
private String itemId;
#CassandraType(type = DataType.Name.LIST, userTypeName = "volume_scale_1")
private List<VolumeScale> volumeScale1;
}
So I am getting volumeScale1 as null after database select query.
And this is how my UDT looks like:
In Cassandra database:
CREATE TYPE pricingservice.volume_scale (
from_scale int,
to_scale int,
value frozen<price_value>
);
As UDT in java :
#UserDefinedType("volume_scale")
public class VolumeScale
{
#CassandraType(type = DataType.Name.TEXT, userTypeName = "from_scale")
#Column("from_scale")
private String fromScale;
#CassandraType(type = DataType.Name.TEXT, userTypeName = "to_scale")
#Column("to_scale")
private String toScale;
#CassandraType(type = DataType.Name.UDT, userTypeName = "value")
private PriceValue value;
// getter and setter
}
I also tried using Object Mapper from java driver itself as per #Alex suggestion but got stuck at one point where creating an object using ItemPriceByMaterialMapperBuilder is throwing compilation error. Is anything additional required towards annotation processing or am I missing something? do you have any idea how to use Mapper annotation? I used google AutoService also to achieve annotation processing externally but didn't work.
#Mapper
//#AutoService(Processor.class)
public interface ItemPriceByMaterialMapper
// extends Processor
{
static MapperBuilder<ItemPriceByMaterialMapper> builder(CqlSession session) {
return new ItemPriceByMaterialMapperBuilder(session);
}
#DaoFactory
ItemPriceByMaterialDao itemPriceByMaterialDao ();
// #DaoFactory
// ItemPriceByMaterialDao itemPriceByMaterialDao(#DaoKeyspace CqlIdentifier
// keyspace);
}
Version used:
Java Version: 1.8
DataStax OSS java-driver-mapper-processor: 4.5.1
DataStax OSS java-driver-mapper-runtime: 4.5.1
Cassandra: 3.11.4
Spring Boot Framework: 2.2.4.RELEASE
From what I understand, you have multiple problems: if you're using Spring Data Cassandra, then you'll get older driver (3.7.2 for Spring 2.2.6-RELEASE), and it may clash with driver 4.0.0 (it's too old, don't use it) that you're trying to use. Driver 4.x isn't binary compatible with previous drivers, and its support in Spring Data Cassandra could be only in the next major release of Spring.
Instead of Spring Data you can use Object Mapper from java driver itself - it could be more optimized than Spring version.
I decided not to use object mapper and work with Spring Data Cassandra with Spring 2.2.6-RELEASE. Thanks

How to get an instance of Jasper PdfExporterConfiguration?

We're using JasperReports plugin for Grails to generate PDF server-side, using JasperService and JasperReportDef. We recently updated the plugin and JasperReports and discovered that JRPdfExporterParameter is now deprecated in favour of PdfExporterConfiguration
We had code like this:
def reportDef = new JasperReportDef([
name : templateName,
fileFormat : JasperExportFormat.PDF_FORMAT,
reportData : exportRows,
parameters : [
(JRPdfExporterParameter.METADATA_AUTHOR) : 'Company Name'
],
])
Deprecation JavaDoc suggests using PdfExporterConfiguration.getMetadataAuthor() instead. But it's an instance method - and PdfExporterConfiguration is just an interface! - while JRPdfExporterParameter.METADATA_AUTHOR is a static constant.
Where can I get an instance of PdfExporterConfiguration to use?
I use this (note pure java never worked with Grails):
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
it implements the PdfExporterConfiguration and you can set the METADATA.
configuration.setMetadataAuthor("Petter");
Don't know how any other classes that implements PdfExporterConfiguration, let me know if you find some.

CRM 2011 PLUGIN to update another entity

My PLUGIN is firing on Entity A and in my code I am invoking a web service that returns an XML file with some attributes (attr1,attr2,attr3 etc ...) for Entity B including GUID.
I need to update Entity B using the attributes I received from the web service.
Can I use Service Context Class (SaveChanges) or what is the best way to accomplish my task please?
I would appreciate it if you provide an example.
There is no reason you need to use a service context in this instance. Here is basic example of how I would solve this requirement. You'll obviously need to update this code to use the appropriate entities, implement your external web service call, and handle the field updates. In addition, this does not have any error checking or handling as should be included for production code.
I made an assumption you were using the early-bound entity classes, if not you'll need to update the code to use the generic Entity().
class UpdateAnotherEntity : IPlugin
{
private const string TARGET = "Target";
public void Execute(IServiceProvider serviceProvider)
{
//PluginSetup is an abstraction from: http://nicknow.net/dynamics-crm-2011-abstracting-plugin-setup/
var p = new PluginSetup(serviceProvider);
var target = ((Entity) p.Context.InputParameters[TARGET]).ToEntity<Account>();
var updateEntityAndXml = GetRelatedRecordAndXml(target);
var relatedContactEntity =
p.Service.Retrieve(Contact.EntityLogicalName, updateEntityAndXml.Item1, new ColumnSet(true)).ToEntity<Contact>();
UpdateContactEntityWithXml(relatedContactEntity, updateEntityAndXml.Item2);
p.Service.Update(relatedContactEntity);
}
private static void UpdateContactEntityWithXml(Contact relatedEntity, XmlDocument xmlDocument)
{
throw new NotImplementedException("UpdateContactEntityWithXml");
}
private static Tuple<Guid, XmlDocument> GetRelatedRecordAndXml(Account target)
{
throw new NotImplementedException("GetRelatedRecordAndXml");
}
}

EF 5 Re-Use entity configuration

I'm trying to re-use some of the model configurations on several entities that implements a interface.
Check this code:
public static void ConfigureAsAuditable<T>(this EntityTypeConfiguration<T> thisRef)
where T : class, IAuditable
{
thisRef.Property(x => x.CreatedOn)
.HasColumnName("utctimestamp")
.IsRequired();
thisRef.Property(x => x.LastUpdate)
.HasColumnName("utclastchanged")
.IsRequired();
} // ConfigureAsAuditable
as you can see I'm trying to call the extension method "ConfigureAsAuditable" on my onmodelcreating method like this:
EntityTypeConfiguration<Account> conf = null;
conf = modelBuilder.Entity<Account>();
conf.ToTable("dbo.taccount");
conf.ConfigureAsAuditable();
When debugging i get this exception:
The property 'CreatedOn' is not a declared property on type
'Account'. Verify that the property has not been explicitly excluded
from the model by using the Ignore method or NotMappedAttribute data
annotation. Make sure that it is a valid primitive property.
Thanks in advance :)
PD:
I'm using EF 5-rc, VS 2011 and .NET Framework 4.5
I think a better approach would be to implement your own derived version of EntityTypeConfiguration. For example:
public class MyAuditableConfigurationEntityType<T> : EntityTypeConfiguration<T>
where T : class, IAuditable{
public bool IsAuditable{get;set;}
}
Then, when building your model, use that new type:
var accountConfiguration = new MyAuditableConfigurationEntityType<Account>();
accountConfiguration.IsAuditable = true; // or whatever you need to set
accountConfiguration.(HasKey/Ignore/ToTable/Whatever)
modelBuilder.Configurations.Add(accountConfiguration);

Resources