这个问题已被多次询问,但没有一个答案似乎对我有帮助,所以我会再次尝试再问一遍并希望运气:
我的课程得分
@Entity(name="SokoTable")
public class Score implements Serializable{
@Column(name="ID")
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private private SimpleIntegerProperty id;
@Column(name="Username")
private SimpleStringProperty userName;
@Column(name="Level")
private SimpleStringProperty levelName;
@Column(name="Steps")
private SimpleIntegerProperty steps;
@Column(name="Time")
private SimpleIntegerProperty time;
public Score(){
}
public Score(String userName, String levelName, int steps, int time) {
super();
this.userName = new SimpleStringProperty(userName);
this.levelName = new SimpleStringProperty(levelName);
this.steps = new SimpleIntegerProperty(steps);
this.time = new SimpleIntegerProperty(time);
}
public int getId() {
return id.get();
}
public void setId(int id) {
this.id.set(id);
}
public String getUserName() {
return userName.get();
}
public void setUserName(String userName) {
this.userName.set(userName);
}
public String getLevelName() {
return levelName.get();
}
public void setLevelName(String levelName) {
this.levelName.set(levelName);
}
public int getSteps() {
return steps.get();
}
public void setSteps(int steps) {
this.steps.set(steps);
}
public int getTime() {
return time.get();
}
public void setTime(int time) {
this.time.set(time);
}
}
将管理数据库的 SokoDBManager 类
public class SokoDBManager {
private static SessionFactory factory;
private static SokoDBManager instance=new SokoDBManager() ;
public static SokoDBManager getInstance() {
return instance;
}
private SokoDBManager() {
Configuration configuration = new Configuration();
configuration.configure();
factory = configuration.buildSessionFactory();
}
private static void searchScoresWhoseNameStartsWith(String prefix) {
Session session = factory.openSession();
Query query = session.createQuery("from SokoTable where Username LIKE :prefix");
query.setParameter("prefix", prefix + "%");
List<Score> list = query.list();
for (Score e : list) {
System.out.println(e.getUserName());
}
session.close();
}
public void addScore(Score score){
Session session = null;
Transaction tx = null;
try {
session = factory.openSession();
tx = session.beginTransaction();
session.save(score);
tx.commit();
}
catch (HibernateException ex) {
if (tx != null)
tx.rollback();
System.out.println(ex.getMessage());
}
finally {
if (session != null)
session.close();
}
}
// Method to print all Scores
public static ObservableList<Score> getScoreList(String Levelname) {
Session session = factory.openSession();
ObservableList<Score> list=null;
try {
Query query = session.createQuery("from SokoDB.Score where Level =:Levelname Order by Steps");
query.setParameter("Levelname",Levelname);
list = FXCollections.observableArrayList(query.list());
System.out.println(list.getClass());
for (Score e : list) {
System.out.println(e.getUserName());
}
} catch (HibernateException e) {
e.printStackTrace();
} finally {
session.close();
}
return list;
}
public void close() {
factory.close();
}
}
例如,如果我尝试运行此代码:
ObservableList<Score> data=SokoDBManager.getScoreList("Level 1");
for(Score e :data)
System.out.println(e.getTime());
我会收到此错误:
Caused by: java.lang.ExceptionInInitializerError
at view.SokobanViewer.openFile(SokobanViewer.java:64)
... 53 more
Caused by: org.hibernate.MappingException: Could not determine type for: javafx.beans.property.SimpleStringProperty, at table: SokoTable, for columns: [org.hibernate.mapping.Column(Level)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:455)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:422)
at org.hibernate.mapping.Property.isValid(Property.java:226)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:597)
at org.hibernate.mapping.RootClass.validate(RootClass.java:265)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
at SokoDB.SokoDBManager.<init>(SokoDBManager.java:29)
at SokoDB.SokoDBManager.<clinit>(SokoDBManager.java:21)
... 54 more
它与SimpleStringProperty有关吗? 可能是这个错误的原因,我该如何解决? 感谢
答案 0 :(得分:1)
You want Hibernate to "see" the properties as having the underlying types String
and int
, not the types used for implementing observability by JavaFX (StringProperty
and IntegerProperty
).
If you place the Column
annotation on the fields, Hibernate will use an AccessType
of FIELD
, i.e. it will match the type based on the type of the field. To use an AccessType
of PROPERTY
, in which Hibernate looks at the get/set
methods, not the fields, annotate the get
methods instead. You can also explicitly specify the access type with the Access
annotation.
Also, as an aside, note that you have a bug in the implementation of your entity. If you call the default constructor, and then a set
method (which is exactly what Hibernate will do), you get a null pointer exception as you never instantiate the property instances. It's best to make these final and instantiate them inline.
@Entity(name="SokoTable")
// the next line is optional if you annotate the get methods (as done below):
@Access("AccessType.PROPERTY")
public class Score implements Serializable{
private final IntegerProperty id = new SimpleIntegerProperty() ;
private final StringProperty userName = new SimpleStringProperty() ;
private final StringProperty levelName = new SimpleStringProperty() ;
private final IntegerProperty steps = new SimpleIntegerProperty() ;
private final IntegerProperty time = new SimpleIntegerProperty() ;
public Score(){
}
public Score(String userName, String levelName, int steps, int time) {
super();
setUserName(userName);
setLevelName(levelName);
setSteps(steps);
setTime(time);
}
@Column(name="ID")
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return id.get();
}
public void setId(int id) {
this.id.set(id);
}
@Column(name="Username")
public String getUserName() {
return userName.get();
}
public void setUserName(String userName) {
this.userName.set(userName);
}
@Column(name="Level")
public String getLevelName() {
return levelName.get();
}
public void setLevelName(String levelName) {
this.levelName.set(levelName);
}
@Column(name="Steps")
public int getSteps() {
return steps.get();
}
public void setSteps(int steps) {
this.steps.set(steps);
}
@Column(name="Time")
public int getTime() {
return time.get();
}
public void setTime(int time) {
this.time.set(time);
}
}
Have a look at this blog post for more details.