Eclipse JPA プロジェクトを使用して、Apache Derby でエンティティを作成しています。私はJPAツールを使用しています:
"generate tables from entities.."
指図。このコマンドを使用すると、テーブルがデータベースに入れられます。テーブルが表示され、Eclipse の「データ ソース エクスプローラー」からの列が含まれていることがわかります。ijを介してDerbyにログインすると。
私はタイプする:
'show tables in schema x';
エンティティに対応するテーブル名のリストを取得します。私はタイプする:
'select * from <table in x>'
私は得る:
ERROR 42X05: Table/View 'ADDRESS' does not exist.
テーブルがくっつかないのはなぜですか..? 「エンティティからテーブルを生成..」コマンドの使用中に入力されている CREATE TABLE コマンドを使用すると、そこにテーブルが作成されます。「select * ..」と入力すると、テーブルが表示されます。
第二に、おそらく関連する問題。クラスがあります。次のコマンドを使用して、エンティティ マネージャーを取得します。
EntityManagerFactory emf = Persistence.createEntityManagerFactory("DataModelAccess");
EntityManager em = emf.createEntityManager();
次のように、エンティティに対してテストを実行すると、次のようになります。
public void runTest()
{
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("DataModelAccess");
EntityManager em = emf.createEntityManager();
System.out.println(emf == null);
Address address = new Address();
address.setAddressID("1");
address.setAddressNumber(1746);
address.setStreetName("Howard");
address.setStreetType("Court");
address.setCity("Lennyville");
address.setState("CT");
address.setZipcode(73625);
em.persist(address);
em.close();
emf.close();
// reassign:
emf = Persistence.createEntityManagerFactory("DataModelAccess");
em = emf.createEntityManager();
Address address2 = em.find(Address.class, "1");
System.out.println(address2.getCity());
最終行で NullPointerException が発生します。
emf と em に再割り当てしないと、都市がコンソールに出力されます。
そう、
1. SELECT * FROM <TABLE_NAME> でテーブルが表示されないのはなぜですか?
しかし、SHOW TABLES IN <SCHEMA> には表示されますか?
2. セッション間でデータが保持されないのはなぜですか?
私はこれを Eclipse で、普通の古い Java SE オブジェクトから実行しています。Java EE コンテナーはありません。これは Eclipse JPA プロジェクトです。persistence.xml ファイルがあります。Eclipse が管理する「derby」という接続があります。もしかしたら、persistence.xml ファイルに問題があるのでしょうか? たぶん、これは誰にとっても共通の問題です。おそらく、アクセスプロトコルが異なるため、JPAとeclipselinkはデフォルトでこれを行いますか? Java EE コンテナーがないことが、それを難しくしているのではないでしょうか?
========
要求どおり: アドレス クラスはまったく無関係です。フィールドベースとプロパティベースの両方のアクセスも試しました。IJと変わりません。どちらの試みも同様に失敗します。これは要約です:
@Entity
@Table(name="ADDRESS")
public class Address
implements Serializable
...
@Id
public String getAddressID()
それ以外はすべて、フィールド、コンストラクター、ゲッター、セッターです。注釈はありません。パッケージを右クリックして選択し、新しい JPA エンティティを追加しました。
New --> JPA Entity
Eclipseウィザードを使用してフィールドを入れました。プロパティベースにしました。フィールドベースのアクセスで何かが変わるのではないかと思ったので、フィールドベースで試してみましたが、違いはありませんでした。
これが表示される場所: address.setStreetName("Howard"); フィールドがあります:
private String streetName;
および2つの対応する方法
setStreetName(String x);
と
String getStreetName();
クラス内のすべてのフィールドに同じ式が存在します。各フィールドにはゲッターとセッターがあります。ゲッターとセッター以外のメソッドはありません。getter/setter メソッドのペアごとに 1 フィールド。私が言及した以上の注釈はありません。
参考までに、Address クラスのすべてのプロパティを設定しているわけではありません。テーブル内のフィールドはすべて NULLABLE としてデータベースに入力されました。それでも、IJ は TABLE を見つけられません。– user1405870 11時間前
=========
Address および Address_ クラスは次のとおりです。
package dataAccess.customer;
import javax.annotation.Generated;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;
@Generated(value="Dali", date="2012-05-18T21:44:02.229-0500")
@StaticMetamodel(Address.class)
public class Address_
{
public static volatile SingularAttribute<Address, String> addressID;
public static volatile SingularAttribute<Address, Integer> addressNumber;
public static volatile SingularAttribute<Address, String> streetName;
public static volatile SingularAttribute<Address, String> streetType;
public static volatile SingularAttribute<Address, String> building;
public static volatile SingularAttribute<Address, String> floor;
public static volatile SingularAttribute<Address, String> unit;
public static volatile SingularAttribute<Address, String> landmarkName;
public static volatile SingularAttribute<Address, String> city;
public static volatile SingularAttribute<Address, String> state;
public static volatile SingularAttribute<Address, Integer> zipcode;
}
package dataAccess.customer;
import java.io.Serializable;
import java.lang.Integer;
import java.lang.String;
import javax.persistence.*;
/**
* Entity implementation class for Entity: Address
*
*/
@Entity
@Table(name="ADDRESS")
public class Address
implements Serializable
{
private String addressID;
private Integer addressNumber;
private String streetName;
private String streetType;
private String building;
private String floor;
private String unit;
private String landmarkName;
private String city;
private String state;
private Integer zipcode;
private static final long serialVersionUID = 1L;
public Address()
{
}
@Id
public String getAddressID()
{
return addressID;
}
public void setAddressID(String addressID)
{
this.addressID = addressID;
}
public Integer getAddressNumber()
{
return this.addressNumber;
}
public void setAddressNumber(Integer addressNumber)
{
this.addressNumber = addressNumber;
}
public String getStreetName()
{
return this.streetName;
}
public void setStreetName(String streetName)
{
this.streetName = streetName;
}
public String getStreetType()
{
return this.streetType;
}
public void setStreetType(String streetType)
{
this.streetType = streetType;
}
public String getBuilding()
{
return this.building;
}
public void setBuilding(String building)
{
this.building = building;
}
public String getFloor()
{
return this.floor;
}
public void setFloor(String floor)
{
this.floor = floor;
}
public String getUnit()
{
return this.unit;
}
public void setUnit(String unit)
{
this.unit = unit;
}
public String getLandmarkName()
{
return this.landmarkName;
}
public void setLandmarkName(String landmarkName)
{
this.landmarkName = landmarkName;
}
public String getCity()
{
return this.city;
}
public void setCity(String city)
{
this.city = city;
}
public String getState()
{
return this.state;
}
public void setState(String state)
{
this.state = state;
}
public Integer getZipcode()
{
return this.zipcode;
}
public void setZipcode(Integer zipcode)
{
this.zipcode = zipcode;
}
}
persistence.xml は次のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="DataModelAccess" transaction-type="RESOURCE_LOCAL">
<class>dataAccess.customer.Person</class>
<class>dataAccess.customer.Address</class>
<class>dataAccess.customer.PhoneNumber</class>
<class>dataAccess.customer.Customer</class>
<class>dataAccess.customer.TwoFieldTest</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.ddl-generation.output-mode" value="database"></property>
<property name="eclipselink.target-database" value="derby"/>
<property name="eclipselink.target-server" value="None"/>
<property name="eclipselink.exclude-eclipselink-orm" value="true"/>
<property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
<property name="eclipselink.jdbc.cache-statements" value="true"/>
<property name="eclipselink.jdbc.native-sql" value="true"/>
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/sample;create=true"/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="eclipselink.jdbc.bind-parameters" value="false"/>
<property name="eclipselink.jdbc.exclusive-connection.mode" value="Transactional"/>
<property name="eclipselink.orm.validate.schema" value="true"/>
<property name="eclipselink.orm.throw.exceptions" value="true"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>
コメント:
呼び出し
em.flush();
データがセッション間で永続化されているかどうかを確認するために、まさに私が行ったことです(そうではありません)。つまり、メソッド「runTest()」を実行すると、元の runTest() メソッドの下に正しい印刷ステートメントが表示されます。変更された「runTest()」メソッドを投稿しました (「コメントの再割り当て」を参照してください)。ここで、address、phoneNumber、person の 3 つのエンティティから構築する顧客がいる場合、エンティティ マネージャーを使用して、「データベース内」の他の 3 つのエンティティを検索することで顧客をインスタンス化できます。ただし、データベース内の 3 つのエンティティを検索して新しい顧客を作成するコードを除いてすべてをコメントアウトすると、データベースからデータを取得できないことがわかります。
次のようになります。
Customer c = new Customer();
c.setAddress(em.find(Address.class, "1"));
c.setPhoneNumber(em.find(PhoneNumber.class, "1"));
c.setName(em.find(Person.class, "1"));
c.setCustomerID("123");
em.persist(c);
*/
Customer actual = em.find(Customer.class, "123");
そして、em.persist(c) の後まですべてをコメントアウトすると、実際の Customer が得られません。
通常、私はこれを取得します:
Customer:
Name:
Mr. Howard T Stewart III
Address:
1746 Howard Court
Lennyville, CT 73625
Phone:
(215) 256-4563
しかし、私がすべてをコメントアウトすると
Customer actual = em.find(Customer.class, "123");
(今.. 前の行で em をインスタンス化しましたが、今は person、phone_number、または address を作成していません。)
それから、..私は、
(actual == null)
true と評価されます。
「find()」コマンドを誤用していませんか? データベースまたは何かへの現在の接続をロードするために何か他のことをすることになっていますか(em(em.method())を介したコマンドに関して)?
ここには Java EE コンテナーがないことに注意してください。私はEclipseでこれを行っており、eclipselink 2.3を使用して、EclipseのJPAプロジェクトでj2seプログラムでメインメソッドを実行しています。しかし、これは EJB ではなく、ManagedBeans などでもありません。
そう..
私はこれを見つけました:
@Resource
UserTransaction utx;
...
try {
utx.begin();
bookDBAO.buyBooks(cart);
utx.commit();
} catch (Exception ex) {
try {
utx.rollback();
} catch (Exception exe) {
System.out.println("Rollback failed: "+exe.getMessage());
}
...
残念ながら、Java ee チュートリアルの Web 部分にたどり着くまで UserTransaction について何も見つけられなかったので、em.persist( )必要なすべてです。また、@Resource は Java EE コンテナの外では機能しない場合があります。
ダニエル: コメントありがとうございます。必要な答えが得られました。
上記のアイテムを見つけましたが、これを行っていましたが:
em.getTransaction().begin();
// .. set fields of address ..
em.persist(address);
em.getTransaction().commit();
em.close();
それはまだ機能していませんでした。persistence.xml ファイルを CREATE テーブルのみに変更すると、テスト メソッドが正しく実行され、すべてをコメント アウトしてデータベースから顧客を取得すると、それも正しく返されます。
私も試しました:
SELECT * FROM <SCHEMA>.ADDRESS;
それもうまくいきます。「DROP AND CREATE TABLES」ディレクティブのためにエンティティマネージャーが実際に何をしているかを見つけることは、チュートリアルの中で追跡するのが非常に難しいことです。