Goal: Generate (PostgreSQL) SQL table definition (DDL) from entities. The table definition is based on the entity name and the fields (the name, the type and the annotations).
First the name of the entity is converted to lower case and made plural (add a 's' at the end),
e.g. the Student entity, becomes the students table.
Second all Java types are converted to their respective SQL types, see table Mapping of types from Java to SQL . This relation is already given in the class TypeMappings.
The annotations on the fields are converted into different types or into restrictions, see the list below.
-
@IDshould generate aSERIAL(if the field is an integer) orBIGSERIAL(if the field is a long) and have thePRIMARY KEYattribute. -
@NotNullshould result in aNOT NULLconstraint. -
@Checkshould copy the value (text) of the annotation as parameter to theCHECKconstraint. -
@Defaultshould copy the value as theDEFAULTvalue. Quote the value where needed.
| Java | SQL |
|---|---|
java.lang.String |
TEXT |
java.lang.Character |
CHAR(1) |
java.lang.Integer |
INTEGER |
int |
INTEGER |
java.lang.Short |
SMALLINT |
short |
SMALLINT |
java.lang.Long |
BIGINT |
long |
BIGINT |
java.math.BigDecimal |
DECIMAL |
java.math.BigInteger |
NUMERIC |
java.lang.Float |
REAL |
float |
REAL |
java.lang.Double |
DOUBLE PRECISION |
double |
DOUBLE PRECISION |
java.time.LocalDate |
DATE |
java.time.LocalDateTime |
TIMESTAMP |
Given the entity below:
public class CourseModule {
@ID
private Integer moduleid;
@NotNull
String name;
@NotNull
@Default(value = "5")
@Check(value = "credits > 0")
Integer credits;
// extra ctor to make the default values take effect.
public CourseModule( Integer moduleid, String name ) {
this( moduleid, name, 5 );
}
}The output should look like:
CREATE TABLE coursemodules (
moduleid SERIAL PRIMARY KEY,
name TEXT NOT NULL,
credits INTEGER NOT NULL DEFAULT (5) CHECK (credits > 0)
);-
Start by implementing
GeneratorTestBase-
Implement the
startWithCREATEmethod-
Assert that the first line starts with
CREATE TABLE -
Use the
tableDefinitionto get the first line
-
-
Implement the
tableNamemethod-
Assert that the correct table name is used in the
CREATE TABLEstatement -
Again use the
tableDefinitionto get the first line and assert thattableNameis present
-
-
Implement
assertTypeConversion-
Use
SoftAssertions -
Assert that the column for the given fieldname is present (
columnDefinition) -
Assert that the column definition is as expected (
expectedDefinition)
-
-
-
Implement
PGTableCreator-
Start by implementing
createTable -
Implement
processAnnotations-
Use a
StringBuilderto store the intermediate result -
Retrieve the annotations from the provided
field -
To compare a retrieved
Annotationwith anAnnotation, e.g.NotNullyou can useannotationTypeto retrieve the class from theAnnotationand then compare usingannotation.annotationType() == NotNull.class -
Check the [annotations] rules
-
For the
@IDannotation it might be easiest to override thepgTypeNameto the correct type
-
-
-