Skip to content

Commit e9d956c

Browse files
Implement multi-schema support
1 parent 3126d8c commit e9d956c

18 files changed

+667
-15
lines changed

src/main/java/liquibase/ext/hibernate/database/HibernateDatabase.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,11 @@ public abstract class HibernateDatabase extends AbstractJdbcDatabase {
3636
protected Dialect dialect;
3737

3838
private boolean indexesForForeignKeys = false;
39-
public static final String DEFAULT_SCHEMA = "HIBERNATE";
39+
public static final String DEFAULT_DEFAULT_CATALOG_NAME = "HIBERNATE";
40+
public static final String DEFAULT_DEFAULT_SCHEMA_NAME = "HIBERNATE";
4041
public static final String HIBERNATE_TEMP_USE_JDBC_METADATA_DEFAULTS = "hibernate.temp.use_jdbc_metadata_defaults";
4142

42-
public HibernateDatabase() {
43-
setDefaultCatalogName(DEFAULT_SCHEMA);
44-
setDefaultSchemaName(DEFAULT_SCHEMA);
45-
}
43+
public HibernateDatabase() { }
4644

4745
public boolean requiresPassword() {
4846
return false;
@@ -295,23 +293,28 @@ public boolean supportsTablespaces() {
295293
}
296294

297295
@Override
298-
protected String getConnectionCatalogName() throws DatabaseException {
299-
return getDefaultCatalogName();
296+
protected String getConnectionCatalogName() {
297+
return DEFAULT_DEFAULT_CATALOG_NAME;
300298
}
301299

302300
@Override
303301
protected String getConnectionSchemaName() {
304-
return getDefaultSchemaName();
302+
return DEFAULT_DEFAULT_SCHEMA_NAME;
305303
}
306304

307305
@Override
308306
public String getDefaultSchemaName() {
309-
return DEFAULT_SCHEMA;
307+
final String defaultSchemaName = super.getDefaultSchemaName();
308+
if (defaultSchemaName != null) {
309+
return defaultSchemaName;
310+
}
311+
312+
return DEFAULT_DEFAULT_SCHEMA_NAME;
310313
}
311314

312315
@Override
313316
public String getDefaultCatalogName() {
314-
return DEFAULT_SCHEMA;
317+
return DEFAULT_DEFAULT_CATALOG_NAME;
315318
}
316319

317320
@Override
@@ -334,6 +337,9 @@ public boolean supportsCatalogs() {
334337
return true;
335338
}
336339

340+
@Override
341+
public void setDefaultCatalogName(String defaultCatalogName) { }
342+
337343
/**
338344
* Used by hibernate to ensure no database access is performed.
339345
*/

src/main/java/liquibase/ext/hibernate/snapshot/SchemaSnapshotGenerator.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package liquibase.ext.hibernate.snapshot;
22

3+
import liquibase.Scope;
34
import liquibase.exception.DatabaseException;
45
import liquibase.snapshot.DatabaseSnapshot;
56
import liquibase.snapshot.InvalidExampleException;
@@ -18,7 +19,12 @@ public SchemaSnapshotGenerator() {
1819

1920
@Override
2021
protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException {
21-
return new Schema(snapshot.getDatabase().getDefaultCatalogName(), snapshot.getDatabase().getDefaultSchemaName()).setDefault(true);
22+
Schema schema = new Schema(example.getSchema().getCatalog(), example.getSchema().getName());
23+
if (snapshot.getDatabase().getDefaultSchemaName() != null && snapshot.getDatabase().getDefaultSchemaName().equalsIgnoreCase(schema.getName())) {
24+
schema.setDefault(true);
25+
}
26+
27+
return schema;
2228
}
2329

2430
@Override

src/main/java/liquibase/ext/hibernate/snapshot/SequenceSnapshotGenerator.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot) thro
3434
Schema schema = (Schema) foundObject;
3535
HibernateDatabase database = (HibernateDatabase) snapshot.getDatabase();
3636
for (org.hibernate.boot.model.relational.Namespace namespace : database.getMetadata().getDatabase().getNamespaces()) {
37+
boolean namespaceMatchesSchema = (namespace.getName().getSchema() != null && namespace.getName().getSchema().matches(foundObject.getName()))
38+
|| (namespace.getName().getSchema() == null && ((Schema) foundObject).isDefault());
39+
if (!namespaceMatchesSchema) {
40+
continue;
41+
}
42+
3743
for (org.hibernate.boot.model.relational.Sequence sequence : namespace.getSequences()) {
3844
schema.addDatabaseObject(new Sequence()
3945
.setName(sequence.getName().getSequenceName().getText())

src/main/java/liquibase/ext/hibernate/snapshot/TableSnapshotGenerator.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
import liquibase.structure.core.Table;
1313
import org.hibernate.boot.spi.MetadataImplementor;
1414
import org.hibernate.generator.Generator;
15-
import org.hibernate.mapping.*;
15+
import org.hibernate.mapping.Join;
16+
import org.hibernate.mapping.PersistentClass;
17+
import org.hibernate.mapping.RootClass;
18+
import org.hibernate.mapping.SimpleValue;
1619

1720
import java.util.ArrayList;
1821
import java.util.Collection;
@@ -38,13 +41,21 @@ protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot
3841
return example;
3942
}
4043

41-
Table table = new Table().setName(hibernateTable.getName());
42-
Scope.getCurrentScope().getLog(getClass()).info("Found table " + table.getName());
44+
boolean schemaMatches = (example.getSchema().getName() != null && example.getSchema().getName().equalsIgnoreCase(hibernateTable.getSchema()))
45+
|| (example.getSchema().isDefault() && hibernateTable.getSchema() == null);
46+
if (!schemaMatches) {
47+
Scope.getCurrentScope().getLog(getClass()).info("Skipping table " + hibernateTable.getName() + " for schema " + example.getSchema().getName() + ", because it is part of another one.");
48+
return null;
49+
}
50+
51+
Table table = new Table();
52+
table.setName(hibernateTable.getName());
4353
table.setSchema(example.getSchema());
4454
if (hibernateTable.getComment() != null && !hibernateTable.getComment().isEmpty()) {
4555
table.setRemarks(hibernateTable.getComment());
4656
}
4757

58+
Scope.getCurrentScope().getLog(getClass()).info("Found table " + example.getSchema().getName() + "." + table.getName());
4859
return table;
4960
}
5061

@@ -115,7 +126,6 @@ protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot) thro
115126
private void addDatabaseObjectToSchema(org.hibernate.mapping.Table join, Schema schema, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException {
116127
Table joinTable = new Table().setName(join.getName());
117128
joinTable.setSchema(schema);
118-
Scope.getCurrentScope().getLog(getClass()).info("Found table " + joinTable.getName());
119129
schema.addDatabaseObject(snapshotObject(joinTable, snapshot));
120130
}
121131
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.example.multischema.auction;
2+
3+
import jakarta.persistence.Column;
4+
import jakarta.persistence.Entity;
5+
import jakarta.persistence.Id;
6+
import jakarta.persistence.Table;
7+
8+
import java.util.Date;
9+
10+
@Entity
11+
@Table(schema = "PUBLIC")
12+
public class AuctionInfo {
13+
private String id;
14+
private String description;
15+
private Date ends;
16+
private Float maxAmount;
17+
18+
@Column(length = 1000)
19+
public String getDescription() {
20+
return description;
21+
}
22+
23+
public Date getEnds() {
24+
return ends;
25+
}
26+
27+
@Id
28+
public String getId() {
29+
return id;
30+
}
31+
32+
33+
public Float getMaxAmount() {
34+
return maxAmount;
35+
}
36+
37+
public void setId(String id) {
38+
this.id = id;
39+
}
40+
41+
public void setDescription(String description) {
42+
this.description = description;
43+
}
44+
45+
public void setEnds(Date ends) {
46+
this.ends = ends;
47+
}
48+
49+
public void setMaxAmount(Float maxAmount) {
50+
this.maxAmount = maxAmount;
51+
}
52+
53+
public AuctionInfo(String id, String description, Date ends, Float maxAmount) {
54+
this.id = id;
55+
this.description = description;
56+
this.ends = ends;
57+
this.maxAmount = maxAmount;
58+
}
59+
60+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.example.multischema.auction;
2+
3+
import jakarta.persistence.*;
4+
5+
import java.util.Date;
6+
import java.util.List;
7+
8+
@Entity
9+
@Table(schema = "PUBLIC")
10+
public class AuctionItem extends Persistent {
11+
private String description;
12+
private String shortDescription;
13+
private List<Bid> bids;
14+
private Bid successfulBid;
15+
private User seller;
16+
private Date ends;
17+
private int condition;
18+
19+
@OneToMany(mappedBy = "item", cascade = CascadeType.ALL)
20+
public List<Bid> getBids() {
21+
return bids;
22+
}
23+
24+
@Column(length = 1000)
25+
public String getDescription() {
26+
return description;
27+
}
28+
29+
@ManyToOne
30+
public User getSeller() {
31+
return seller;
32+
}
33+
34+
@ManyToOne
35+
public Bid getSuccessfulBid() {
36+
return successfulBid;
37+
}
38+
39+
public void setBids(List<Bid> bids) {
40+
this.bids = bids;
41+
}
42+
43+
public void setDescription(String string) {
44+
description = string;
45+
}
46+
47+
public void setSeller(User user) {
48+
seller = user;
49+
}
50+
51+
public void setSuccessfulBid(Bid bid) {
52+
successfulBid = bid;
53+
}
54+
55+
public Date getEnds() {
56+
return ends;
57+
}
58+
59+
public void setEnds(Date date) {
60+
ends = date;
61+
}
62+
63+
public int getCondition() {
64+
return condition;
65+
}
66+
67+
public void setCondition(int i) {
68+
condition = i;
69+
}
70+
71+
public String toString() {
72+
return shortDescription + " (" + description + ": " + condition
73+
+ "/10)";
74+
}
75+
76+
@Column(length = 200)
77+
public String getShortDescription() {
78+
return shortDescription;
79+
}
80+
81+
public void setShortDescription(String shortDescription) {
82+
this.shortDescription = shortDescription;
83+
}
84+
85+
86+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.example.multischema.auction;
2+
3+
import jakarta.persistence.*;
4+
import org.hibernate.envers.Audited;
5+
6+
@Audited
7+
@Entity
8+
@Table(schema = "PUBLIC")
9+
public class AuditedItem {
10+
11+
@Id
12+
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AUDITED_ITEM_SEQ")
13+
@SequenceGenerator(name = "AUDITED_ITEM_SEQ", sequenceName = "AUDITED_ITEM_SEQ")
14+
private long id;
15+
@Column(unique = true)
16+
private String name;
17+
18+
public long getId() {
19+
return id;
20+
}
21+
22+
public void setId(long id) {
23+
this.id = id;
24+
}
25+
26+
public String getName() {
27+
return name;
28+
}
29+
30+
public void setName(String name) {
31+
this.name = name;
32+
}
33+
34+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.example.multischema.auction;
2+
3+
import jakarta.persistence.*;
4+
import org.hibernate.annotations.Cache;
5+
import org.hibernate.annotations.CacheConcurrencyStrategy;
6+
7+
import java.util.Date;
8+
9+
@Entity
10+
@Table(schema = "PUBLIC")
11+
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
12+
@DiscriminatorValue("Y")
13+
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
14+
public class Bid extends Persistent {
15+
private AuctionItem item;
16+
private float amount;
17+
private Date datetime;
18+
private User bidder;
19+
20+
@ManyToOne
21+
public AuctionItem getItem() {
22+
return item;
23+
}
24+
25+
public void setItem(AuctionItem item) {
26+
this.item = item;
27+
}
28+
29+
public float getAmount() {
30+
return amount;
31+
}
32+
33+
@Column(nullable = false, name = "datetime")
34+
public Date getDatetime() {
35+
return datetime;
36+
}
37+
38+
public void setAmount(float f) {
39+
amount = f;
40+
}
41+
42+
public void setDatetime(Date date) {
43+
datetime = date;
44+
}
45+
46+
@ManyToOne(optional = false)
47+
public User getBidder() {
48+
return bidder;
49+
}
50+
51+
public void setBidder(User user) {
52+
bidder = user;
53+
}
54+
55+
public String toString() {
56+
return bidder.getUserName() + " $" + amount;
57+
}
58+
59+
@Transient
60+
public boolean isBuyNow() {
61+
return false;
62+
}
63+
64+
}

0 commit comments

Comments
 (0)