2017-09-09 5 views
10

私はJavaとHibernateを学んでいます。現在、私はカスタム物理ネーミング戦略の使い方を理解できません:PhysicalNamingStrategyオブジェクトが実際にインスタンス化されている間に、toPhysicalTableNameまたはtoPhysicalColumnNameメソッドは呼び出されません。少なくとも、デバッガでは見られません。hibernate.cfg.xmlで物理ネーミング戦略を設定するにはどうすればいいですか?

バージョン:Java 1.8、Hibernate 5.2.10.Final、on MacOS 10.12。ここで

は、最小限のプロジェクトだ:

@Entity 
public class Cake { 
    @Id 
    private long id; 
    private String name; 
    private String FLAVOUR; 
    private int sErViNg; 

    public Cake(String name, String flavour, int serving) { 
     this.name = name; 
     this.FLAVOUR = flavour; 
     this.sErViNg = serving; 
    } 

    // getters and setters 

public class Main { 

    public static void main (String[] args) { 
     Transaction tx = null; 

     try (
       SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); 
       Session session = sessionFactory.openSession(); 
     ) { 
      tx = session.beginTransaction(); 

      Cake cake = new Cake("Molten Chocolate Cake", "chocolate", 1); 
      session.save(cake); 

      tx.commit(); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
      if (tx != null ) { 
       tx.rollback(); 
      } 
     } 
    } 
} 

public class AllCapsPhysicalNamingStrategy 
    extends PhysicalNamingStrategyStandardImpl implements Serializable { 

    public static final AllCapsPhysicalNamingStrategy INSTANCE 
     = new AllCapsPhysicalNamingStrategy(); 

    @Override 
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) { 
     return new Identifier(name.getText().toUpperCase(), name.isQuoted()); 
    } 

    @Override 
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) { 
     return new Identifier(name.getText().toUpperCase(), name.isQuoted()); 
    } 
} 

<hibernate-configuration> 
    <session-factory> 
     <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
     <property name="hibernate.connection.url">jdbc:mysql://localhost/cake</property> 
     <property name="hibernate.connection.username">root</property> 
     <property name="hibernate.connection.password"></property> 
     <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> 
     <property name="hibernate.hbm2ddl.auto">create</property> 
     <property name="hibernate.physical_naming_strategy">com.example.AllCapsPhysicalNamingStrategy</property> 
     <mapping class="com.example.Cake"/> 
    </session-factory> 
</hibernate-configuration> 

[cake]> SELECT * FROM cake; 
+----+-----------+-----------------------+---------+ 
| id | FLAVOUR | name     | sErViNg | 
+----+-----------+-----------------------+---------+ 
| 0 | chocolate | Molten Chocolate Cake |  1 | 
+----+-----------+-----------------------+---------+ 

私は期待:は、ここで私が得るテーブルです

+----+-----------+-----------------------+---------+ 
| ID | FLAVOUR | NAME     | SERVING | 
+----+-----------+-----------------------+---------+ 
| 0 | chocolate | Molten Chocolate Cake |  1 | 
+----+-----------+-----------------------+---------+ 

は、私がここで間違って何をしているのですか?

+0

どのバージョンのHibernateを使用していますか? –

+0

私は手元にある詳細を編集して編集しました。後のマイナーバージョン。 –

+0

元のコード/設定がうまくいくようです。私はあなたが 'AllCapsPhysicalNamingStrategy'への完全修飾パスがhibernate.cfg.xmlファイルで正しいことを二重チェックしたと仮定しています。 –

答えて

2

設定でも設定できます。

public class Main { 

public static void main (String[] args) { 
    Transaction tx = null; 

    try (
      Configuration configuration =new Configuration(); 
      configuration.setPhysicalNamingStrategy(new AllCapsPhysicalNamingStrategy()); 
      SessionFactory sessionFactory = configuration.configure().buildSessionFactory(); 
      Session session = sessionFactory.openSession(); 
    ) { 
     tx = session.beginTransaction(); 

     Cake cake = new Cake("Molten Chocolate Cake", "chocolate", 1); 
     session.save(cake); 

     tx.commit(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
     if (tx != null ) { 
      tx.rollback(); 
     } 
    } 
    } 
} 
+0

ああああ!これは動作しますが、 '.setPhysicalNamingStrategy'を' .setProperty'に置き換えることはできません。しかし私はそこに欲しいものは何でも置くことはできません。 (XMLまたはsetPropertyで)PhysicalNamingPropertyではないクラスを設定すると、java.lang.ClassCastException:com.example.Cakeがorg.hibernate.boot.model.naming.PhysicalNamingStrategy'にキャストできなくなります。 –

3

これは非常によく文書化されていませんが、残念ながらHibernateはhibernate.cfg.xmlで設定されている特定のプロパティをサポートしていませんようです。 a very old Hibernate forum postから引用すると:

あなただけ hibernate.propertiesまたはhibernate.cfg.xmlでEnvironment.javaクラス指定したプロパティを設定することができます。 などの残りのプロパティNamingStrategyはConfigurationクラスで設定する必要があります。

Shiv Raghuwanshiさんが提案したように、プロパティを削除してConfigurationインスタンスのコードに設定することをお勧めします。

1

設定に間違いはありません。 Configurationオブジェクトを使用しているブートストラップ中の休止状態では、構成オブジェクト自体のconfigプロパティーのを設定する必要があります。プロパティを介して指定されたこれらの設定は無視されます。

はまた、ブートストラップは、Configurationオブジェクトを使用して、休止状態「レガシー」方法(as per official hibernate docs)とみなされ、newer wayは、以下に示すように休止状態をブートストラップするのが推奨されます。

public static void main(String[] args) { 
     Transaction tx = null; 

     StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder() 
       .configure() // using "hibernate.cfg.xml" 
       .build(); 
     Metadata metadata = new MetadataSources(standardRegistry).buildMetadata(); 
     try (
       SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build(); 
       Session session = sessionFactory.openSession();) { 
      tx = session.beginTransaction(); 

      Cake cake = new Cake("Molten Chocolate Cake", "chocolate", 1); 
      session.save(cake); 

      tx.commit(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      if (tx != null) { 
       tx.rollback(); 
      } 
     } 
    } 

これはhibernate.cfg.xmlファイルに休止状態プロパティとして指定された物理的な命名戦略を選択します。

関連する問題