我是Hibernate的新手,不知道是否要使用SessionFactory
或EntityManagerFactory
获取hibernate会话.两者有什么区别?优点缺点?
我有一个JPA持久化对象模型,它包含多对一关系:一个帐户有许多交易.交易有一个帐户.
这是代码的片段:
@Entity
public class Transaction {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(cascade = {CascadeType.ALL},fetch= FetchType.EAGER)
private Account fromAccount;
....
@Entity
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(cascade = {CascadeType.ALL},fetch= FetchType.EAGER, mappedBy = "fromAccount")
private Set<Transaction> transactions;
Run Code Online (Sandbox Code Playgroud)
我能够创建一个Account对象,向其添加事务,并正确地持久保存Account对象.但是,当我创建一个事务,使用现有已经存在的帐户,并持久化事务时,我得到一个例外:
if (account.getId()!=null) {
account = entityManager.merge(account);
}
Transaction transaction = new Transaction(account,"other stuff");
// the below fails with a "detached entity" message. why?
entityManager.persist(transaction);
Run Code Online (Sandbox Code Playgroud)
因此,我能够持久保存包含交易的账户,但不能持有具有账户的交易.我认为这是因为帐户可能没有附加,但这段代码仍然给了我同样的例外:
@Entity
public class Transaction {
@Id …
Run Code Online (Sandbox Code Playgroud) 在我们正在开发的这个应用程序中,我们注意到一个视图特别慢.我分析了视图并注意到hibernate执行了一个查询,即使数据库中只有两个对象要获取,也需要10秒.所有OneToMany
和ManyToMany
关系都是懒惰的,所以这不是问题.在检查正在执行的SQL时,我注意到查询中有超过80个连接.
进一步检查这个问题,我注意到问题是由实体类的深层次结构OneToOne
和ManyToOne
关系引起的.所以,我想,我只是让他们变得懒惰,这应该解决问题.但是,无论是标注@OneToOne(fetch=FetchType.LAZY)
或@ManyToOne(fetch=FetchType.LAZY)
似乎不工作.我得到一个异常,或者它们实际上并没有被代理对象替换,因此是懒惰的.
任何想法我将如何让这个工作?请注意,我不使用persistence.xml
定义关系或配置细节,一切都在java代码中完成.
这是尝试运行我的Web应用程序时引发的错误:
[INFO] WARNING: Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$NonEmbeddedConfiguration.dataSource()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please …
Run Code Online (Sandbox Code Playgroud) 我想我误解了在@ManyToOne
关系背景下级联的意义.
案子:
public class User {
@OneToMany(fetch = FetchType.EAGER)
protected Set<Address> userAddresses;
}
public class Address {
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
protected User addressOwner;
}
Run Code Online (Sandbox Code Playgroud)
这是什么意思cascade = CascadeType.ALL
?例如,如果我从数据库中删除某个地址,我添加的事实如何cascade = CascadeType.ALL
影响我的数据(User
我猜)?
我认为hibernate只考虑带注释的类变量@Column
.但奇怪的是,今天当我添加一个变量(没有映射到任何列,只是我在类中需要的变量)时,它试图将该变量作为列名包含在select语句中并抛出错误 -
'字段列表'中的未知列'team1_.agencyName'
我的课 -
@Entity
@Table(name="team")
public class Team extends BaseObject implements Serializable {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(length=50)
private String name;
@Column(length=10)
private String code;
@Column(name = "agency_id")
private Long agencyId;
private String agencyName; //note: not annotated.
}
Run Code Online (Sandbox Code Playgroud)
仅供参考...我在另一个具有多对多映射的类中使用上面的类
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name="user_team",
joinColumns = { @JoinColumn( name="user_id") },
inverseJoinColumns = @JoinColumn( name="team_id")
)
public Set<Team> getTeams() {
return teams;
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?!
为什么我得到这个例外?
package com.domain.idea;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.AccessType;
/**
* object model for the view [InvestmentReturn].[vMAE_MFE]
*/
@Entity
@Table(name="vMAE_MFE", schema="InvestmentReturn")
@AccessType("field")
public class MAE_MFEView
{
/**
* trade property is a SuggestdTradeRecommendation object
*/
@OneToOne(fetch = FetchType.LAZY , cascade = { CascadeType.PERSIST })
@JoinColumn(name = "suggestedTradeRecommendationID")
private SuggestedTradeRecommendation trade;
/**
* Most Adeverse Excursion value
*/
private int MAE;
public int getMAE()
{
return MAE;
}
/**
* Most Favorable Excursion …
Run Code Online (Sandbox Code Playgroud) Hibernate和Spring Data JPA之间的主要区别是什么?什么时候不应该使用Hibernate或Spring Data JPA?另外,什么时候Spring JDBC模板的性能比Hibernate/Spring Data JPA好?
我正在寻找使用JPA映射枚举的不同方法.我特别想设置每个枚举条目的整数值并仅保存整数值.
@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {
public enum Right {
READ(100), WRITE(200), EDITOR (300);
private int value;
Right(int value) { this.value = value; }
public int getValue() { return value; }
};
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "AUTHORITY_ID")
private Long id;
// the enum to map :
private Right right;
}
Run Code Online (Sandbox Code Playgroud)
一个简单的解决方案是使用EnumType注释和EnumType.ORDINAL:
@Column(name = "RIGHT")
@Enumerated(EnumType.ORDINAL)
private Right right;
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,JPA映射枚举索引(0,1,2)而不是我想要的值(100,200,300).
我找到的两个解决方案似乎并不简单......
这里提出的解决方案使用@PrePersist和@PostLoad将枚举转换为其他字段并将枚举字段标记为瞬态:
@Basic
private int intValueForAnEnum;
@PrePersist
void populateDBFields() {
intValueForAnEnum = …
Run Code Online (Sandbox Code Playgroud) jpa ×10
java ×9
hibernate ×6
orm ×2
spring ×2
annotations ×1
cascade ×1
enums ×1
many-to-one ×1
one-to-many ×1
spring-boot ×1
spring-data ×1