activeandroid: multiple columns as unqiue together in a table - unique

I am trying to make 2 columns as unique together in activeandroid using the solution provided in the link: Two column unique constraint ActiveAndroid but its just not working. Compiler is unable to find the "uniqueGroups" and "ConflictAction". I have imported Column class as well but still not working.
I am currently using activeandroid version 3.0, Looking forward to some solution. Code snippet is given below for reference
#Table(name = "Farmer")
public class Farmer extends Model {
#Column(name = "image_path")
public String image_path;
#Expose
#Column(name = "online_id")
public int online_id;
#Expose
#Column(name = "name", uniqueGroups={"group1"}, onUniqueConflicts={ConflictAction.FAIL})
public String name;

It may be a dependency issue. Check for the appropriate "compile ..." statement that you need to add to the build.gradle file for your app. For ActiveAndroid 3.1.0 you may need: compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
Also, having dependencies added to the project using gradle compile statements like the one above AND jar file dependencies may cause conflicts. Choose one of the two methods to avoid that.

Related

Override primary key generator strategy in Spring Boot when deployed to MySQL

In my application I want to support more databases to which it can be loaded, and for MS SQL Server I have set the identity generator to SEQUENCE
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
Because it can be deployed to MySQL as well, I need somehow to change the generator to IDENTITY since SEQUENCE is not available for MySQL, is there a way to do it programatically ?
The simplest solution would probably be to create your schema without the help of Hibernate (e.g. manage your schema using a tool like Liquibase) and use the DB capabilities for assigning the ids. In your specific scenario, you could probably use strategy = IDENTITY for both DBs (just so that Hibernate delegates the id column management to the DB) and then create an INSTEAD OF INSERT trigger for SQL Server. I'm not sure about performance, though.
If you still want Hibernate to do the job - it's not going to be super easy, but I can think of one option you could try:
Use the #GeneratedValue.name property with your id field:
#Id
#GeneratedValue(name = "my-entity-generator")
private Long id;
Declare two versions of my-entity-generator for the two databases. You need to put them on something that is optional for the entity scan. #GenericGenerator can be put on a package, for instance, so you can use two empty packages and declare the generators corresponding to the two strategies in their respective package-infos (never tried it with Spring, though, so I'm not sure if that will get picked up). You could probably also use two dummy #MappedSuperclasses in two different packages.
So, let's say you end up with one mapped superclass called com.example.mssql.Generators:
#MappedSuperclass
#GenericGenerator(name = "my-entity-generator", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", ...)
public abstract class Generators {}
And another one called com.example.mysql.Generators:
#MappedSuperclass
#GenericGenerator(name = "my-entity-generator", strategy = "org.hibernate.id.IdentityGenerator")
public abstract class Generators {}
Conditionally include the two packages in the entity scan:
#Profile("mysql") // or #ConditionalOnProperty, or your own custom condition
#Configuration
#EntityScan(basePackages = "com.example.mysql")
public class MySqlConfig {}
#Profile("mssql") // or #ConditionalOnProperty, or your own custom condition
#Configuration
#EntityScan(basePackages = "com.example.mssql")
public class MsSqlConfig {}
(of course, for this to work, you need an unconditional #EntityScan on top of e.g. your application class that does not cover the two packages)
Another possible option could be to only have one generator declaration but instead use your own custom generator implementation that detects the DB and then delegates to either an IdentityGenerator or a SequenceStyleGenerator. Thus, you have one option that involves configuration magic and another that involves heavy coding.
(finally, I think you could also use Hibernate mapping XML files and - again - conditionally include them in your mapping, but it's an ancient technique and the documentation is not great)

Why does Spring Data / Hibernate query for table "product_def" when the table is "productDef"?

I'm using Spring Boot 2.3.4 / Spring Data / Hibernate / MySQL 8.
My db table is called "productDef". I have an entity object "ProductDef".
When I do a "list all" query I get this error ...
java.sql.SQLSyntaxErrorException: Table 'mydatabase.product_def' doesn't exist
Why is Hibernate looking for table "product_def"?
I tried adding annotation #Table(name="productDef") to the entity, but that didn't help.
If I rename the db table to "product_def", my code works. But unfortunately I cannot rename the db table names for my project.
What am I missing?
UPDATE:
Solution was to implement a custom PhysicalNamingStrategy to prevent the "productDef" becoming "product_def".
However, while this worked for the #Table name annotation, it did not work for the #Column name annotation.
According to this discussion thread, the ignoring of #Column name annotation is a bug.
Adding this to application.properties:
spring.jpa.properties.hibernate.physical_naming_strategy=com.myapp.dao.RealNamingStrategyImpl
And implementing the class like this:
package com.myapp.dao;
import java.io.Serializable;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
public class RealNamingStrategyImpl extends org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implements Serializable {
public static final PhysicalNamingStrategy INSTANCE = new PhysicalNamingStrategyStandardImpl();
#Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
return new Identifier(name.getText(), name.isQuoted());
}
#Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
return new Identifier(name.getText(), name.isQuoted());
}
}
This is the default Naming Strategy used by Hibernate and defined by JPA 2.0, specifically, the physicalNamingStrategy: it converts camel case to underscores for table and column names.
See: https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/domain/naming.html#PhysicalNamingStrategy
While the purpose of an ImplicitNamingStrategy is to determine that an
attribute named accountNumber maps to a logical column name of
accountNumber when not explicitly specified, the purpose of a
PhysicalNamingStrategy would be, for example, to say that the physical
column name should instead be abbreviated acct_num.
There are multiple ways to specify the PhysicalNamingStrategy to use.
First, applications can specify the implementation using the
hibernate.physical_naming_strategy configuration setting.
With Spring, you can also configure this strategy with the property: spring.jpa.hibernate.naming.physical-strategy
By default, Spring Boot configures the physical naming strategy with
SpringPhysicalNamingStrategy. This implementation provides the same
table structure as Hibernate 4: all dots are replaced by underscores
and camel casing is replaced by underscores as well. By default, all
table names are generated in lower case, but it is possible to
override that flag if your schema requires it.

how to generate tables from spring components with spring-mybatis?

I'm using spring-mybatis and I have configured many components and mappers.
My services are working without any problems but i want to know if is it possible to generate tables from spring component (using annotations #Component) or if I have to Create tables manually so I can execute my mappers methods ?
I've used the following method to do this, but maybe it's a bit hacky.
Create your mapper as normal, but add another interface method to create the table:
#Insert("create table if not exists students (name integer)")
public void createTable();
Then, in your service class, create a method with the #PostContructannotation so that it gets called at startup:
#Autowired
private StudentDao studentMapper;
#PostConstruct
private void setup() {
// setup stuff goes here.
studentMapper.createTable();
// include any other mappers you have...
}
I tried annotating the createTable() method with #PostConstructbut it wasn't executed. Probably because it is an interface.
Hope that helps
Owen

Polymorphic belongsTo in many to many mapping in grails?

So i know this is possible using a superclass, however, this is very limiting in flexibility. So my question is then, can i use an interface? Something ala.
interface Taggable {
/*Adds tag(s) and returns a list of currently set tags*/
List<String> addTags(String ... tag)
/*Removes tag(s) and returns a list of currently set tags*/
List<String> removeTags(String ... tag)
}
class User implements Taggable {
String username
static hasMany = [tags:Tag]
}
class Tag {
String name
static hasMany = [references:Taggable]
static belongsTo = Taggable
static constraints = {
name(nullable: false, blank: false, unique: true)
}
}
Im interested in a reference back to the object who has the following tag. This object however can't extend a concrete class. Thats why im wondering if this can be done with an interface instead.
So, can it be done?
Hibernate can map an interface - see example. I doubt if Grails supports this in by-convention mapping - but you can try using the mapping annotations from example above, or XML config.
edit: answering a comment question:
On a database level, you have to have a Taggable table for Tag.References to reference with a foreign key.
Discriminator will NOT defeat polymorphism, if it's added automatically - for instance, in table-per-hierarchy mapping, Hibernate/Gorm adds a class field in order to find out a concrete class when reading object from db.
If you map your Taggables to two tables - Taggable part to Taggable and everything else to specific table, referenced 1:1 - all the discriminator work should be done for you by Hibernate.
BTW class field is pretty long - it contains fully qualified class name.
edit 2:
Either way, it's getting pretty complex, and I'd personally go with the approach I suggested in another question:
dynamically query all the classes with Taggable interface for hasMany=[tags:Tag] property;
or, less preferable - to have a hand-crafted child table and a discriminator.

Copy constructor using private attributes

My first question here so be gentle.
I would like arguments for the following code:
public class Example {
private String name;
private int age;
...
// copy constructor here
public Example(Example e) {
this.name = e.name; // accessing a private attribute of an instance
this.age = e.age;
}
...
}
I believe this breaks the modularity of the instance passed to the copy constructor.
This is what I believe to be correct:
public class Example {
private String name;
private int age;
...
// copy constructor here
public Example(Example e) {
this.setName(e.getName());
this.setAge(e.getAge());
}
...
}
A friend has exposed a valid point of view, saying that in the copy construct we should create the object as fast as possible. And adding getter/setter methods would result in unnecessary overhead.
I stand on a crossroad. Can you shed some light?
Access is class based, not object based.
The rationale for making a member private is that the ther classes should not know the details of implementation outside of well defined API, so as to make the rest of the system tolerate the change of implementation. However, the copy constructor is not "the rst of the system" - it is your own class.
The first example is not copying a private attribute of an instance, because they are bot instances of the same class.
However, if you add access methods/properties, any decent compiler should optimise them away to simple "inlines", in which case the second method is cleaner code (all accesses go via your access function) but both approaches should end us as be equally efficient (probably identical) memberwise copies.
If you really want a copy constructor to be efficient, then a lower level binary copy will be faster than a memberwise copy. But significantly "dirtier".
In general I prefer to access all member fields via properties/accessors as that encapsulates them better, allowing you to change the underlying implementation/storage of a field without having to change any of the code that accesses it, except for the property/accessor itself.