Ich denke, ich versuche, etwas wirklich einfaches zu tun. Spring-Boot (1.3.3.RELEASE) mit JPA verwenden Ich möchte einen Tabellennamen festlegen.Legen Sie den Tabellennamen im Frühling JPA
@Entity
@Table(name = "MyTable_name")
public class MyTableData {
...
}
Was ich in meiner Datenbank erwarte, ist eine Tabelle mit "MyTable_name". Scheint mir völlig vernünftig. Aber das passiert nicht. Ich bekomme eine Tabelle mit dem Namen "MY_TABLE_NAME" (H2-Backend) oder "my_table_name" (Postgre-Backend). Ab hier bleibe ich bei Postgre, da ich eine vorhandene DB lesen möchte, in der ich die Tabellennamen nicht kontrolliere.
Nach einigen Recherchen finde ich Beiträge, die sagen, dass ich die spring.jpa.hibernate.naming-Strategie-Eigenschaft verwenden sollte. Das hilft nicht viel. Die Einstellung auf die am häufigsten empfohlene org.hibernate.cfg.ImprovedNamingStrategy erzeugt das gleiche Verhalten: "my_table_name". Die Einstellung auf "org.hibernate.cfg.EJB3NamingStrategy" erzeugt "meinTabellenname". Die Einstellung auf org.hibernate.cfg.DefaultNamingStrategy verursacht Anwendungskontextfehler in Spring-Innereien.
Resigniert, um mein eigenes zu schreiben, fing ich an, org.hibernate.cfg.ImprovedNamingStrategy zu betrachten. Ich entdeckte, dass es die veraltete org.hibernate.cfg.NamingStrategy verwendet. Dies schlägt vor, stattdessen NamingStrategyDelegator zu verwenden. Ich schaute auf seine Java docs aber nicht sicher, wie man sich bewirbt. Ich habe this post gefunden. So sehr ich die Erklärung auch schätze, was zu tun ist, ist komplexer als das, was ich brauche, und ich hatte Schwierigkeiten, es anzuwenden.
Meine Frage ist dann, wie kann ich Spring JPA bekommen, nur den Namen zu verwenden, den ich spezifiziere? Gibt es eine neue Eigenschaft für NamingStrategyDelegator? Muss ich meine eigene Strategie schreiben?
=========== aktualisieren ==========================
Ich glaube, ich Ich konvergiere auf eine Antwort. Ich habe eine einfache Spring-Startanwendung erstellt (getrennt von meinem Produktionsprojekt). Ich benutze H2 für die Backend-DB.
This discussion auf Hiberate 5 Naming ist sehr hilfreich. Damit habe ich herausgefunden, wie man Benennungsstrategien in Hibernate 5 wie folgt definiert (in application.properties).
hibernate.implicit_naming_strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
hibernate.physical_naming_strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
habe ich eine physische Namensstrategie, die durch den Namen übergeben (wie org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl der Fall ist) und Werte ausgibt. Von diesem sehe ich, dass Tabellennamen sind, was ich durch die physische Benennungsschicht will.
Ich legte dann Hibernate.show_sql = True zu zeigen, SQL zu generieren. Im generierten SQL sind die Namen auch korrekt.
Ich untersuche Tabellennamen mit DatabaseMetaData.
Ich sehe immer noch Tabellennamen in ALLEN CAPS, wenn ich den obigen Code verwende. Das führt mich zu der Annahme, dass DatabaseMetaData aus irgendeinem Grund Großbuchstaben zeigt, aber der Rest des Codes verwendet die richtigen Namen. [EDIT: Diese Schlussfolgerung ist nicht korrekt. Ich war nur verwirrt von allem anderen, was passierte. Späteres Testen zeigt, dass DatabaseMetaData Tabellennamen mit korrektem Groß-/Kleinbuchstaben anzeigt.]
Dies ist noch keine vollständige Antwort, da ich noch etwas Fremdheit in meinem Produktionscode habe, das ich untersuchen muss. Aber es ist nah dran und ich wollte ein Update veröffentlichen, damit potenzielle Leser keine Zeit verlieren.
Hier ist meine Pass durch physikalische Benennungsstrategie, falls jemand interessiert ist. Ich weiß, dass es helfen kann, zu sehen, was andere getan haben, besonders wenn man versucht, Klassen und Pakete im Labyrinth des Frühlings zu finden.
package my.domain.eric;
import java.io.Serializable;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NamingStrategyPhysicalLeaveAlone implements PhysicalNamingStrategy, Serializable {
private static final long serialVersionUID = -5937286882099274612L;
private static final Logger LOGGER = LoggerFactory.getLogger(NamingStrategyPhysicalLeaveAlone.class);
protected Logger getLogger() {
return LOGGER;
}
@Override
public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment context) {
String nameText = name == null ? "" : name.getText();
getLogger().info("toPhysicalCatalogName name: {}", nameText);
return name;
}
@Override
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment context) {
String nameText = name == null ? "" : name.getText();
getLogger().info("toPhysicalSchemaName name: {}", nameText);
return name;
}
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
String nameText = name == null ? "" : name.getText();
getLogger().info("toPhysicalTableName name: {}", nameText);
return name;
}
@Override
public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment context) {
String nameText = name == null ? "" : name.getText();
getLogger().info("toPhysicalSequenceName name: {}", nameText);
return name;
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
String nameText = name == null ? "" : name.getText();
getLogger().info("toPhysicalColumnName name: {}", nameText);
return name;
}
}
Welchen JPA-Anbieter verwenden Sie? Welche Version? Dein ursprünglicher Code sollte funktionieren. Wenn Sie bereits Tabellen haben, warum generieren Sie die DDL? Es muss etwas anderes geben, das den Tabellennamen für Sie erstellt, da das, was Sie haben, direkt aus dem Hibernate [docs] (https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity) stammt .html # entity-mapping-entity) oder OpenJPA [docs] (https://openjpa.apache.org/builds/2.4.1/apache-openjpa/docs/manual.html#jpa_overview_mapping_table). – JudgingNotJudging
Ich benutze Hibernate 4.3.11.Final. Ich bin mir nicht sicher, warum du denkst, ich erzeuge die DDL (ich bin mir nicht einmal sicher, was du damit meinst). Ich habe eine Entität erstellt, in der Daten gelesen werden können. Meine Tabellen befinden sich bereits in einer vorhandenen Datenbank. Ich habe Tests, die die Datenbank mit H2 simulieren (sie erzeugen Tabellen und ich möchte, dass sie dieselben Namen wie die Tabellen in der realen Datenbank haben). "Es muss etwas anderes geben, das die Tabellennamen erzeugt". Ja, das ist genau meine Frage: Was in Spring/JPA/Hibernate/????? meckert mit meinem erklärten Namen? Und wie repariere ich es? – EricGreg
Ich habe auch Testcode gegen PostgreSQL ausgeführt und somit Tabellen generiert. Vielleicht sind das und meine H2-Kommentare der Grund, warum du denkst, dass ich "die DDL erzeuge". In meinen Tests möchte ich den korrekten Tabellennamen generieren. In meinem Produktionscode möchte ich, dass meine Lese- und Abfragevorgänge auf die korrekten vorhandenen Tabellen verweisen. – EricGreg