我正在使用Spring Boot开发一个相对较大的项目,一般来说我很满意它,但是我遇到了一些问题,在我看来应该不是问题.
首先,一对一的关系.令人沮丧的是它不能正常工作(至少在我看来).
我有两个实体,User
并且UserProfile
,例如.他们有一对一的关系,但大部分时间我只需要User
数据,但它取而代之(无论我尝试什么,哦,男孩,我在5页Google的每篇文章中尝试了世界建议).
所以我的第一个问题是,有没有办法能够在JPA和Spring中实现懒惰的一对一关系?(因为大部分帖子都超过2 - 3年).
我遇到的另一个问题是以"动态"方式构建JSON响应.我使用Rails做了一些事情并且非常满意,JBuilder
甚至to_json
这让我能够根据控制器和我目前的需求构建json响应.
在Spring中,我看到了以下解决方案:
Jackson @JsonView
(这并不完全解决我的问题,因为响应不是静态的,并且属性不能分配给多个视图(据我理解的概念));HashMap
像我.json.jbuilder
在Rails上构建的那样(但是这会破坏我的表现,因为它有很多关系for
来构建json,这看起来像是一个丑陋的演练).我正在寻找某人的某些指示,有朝一日可能会遇到其中一个问题,因为它让我无法解决问题,而在我看来这不应该是这么难.
编辑1
已经尝试添加optional = false
的@OneToOne
注释来解决的OneToOne关系的渴望负荷@snovelli建议.例:
@OneToOne(optional=false, fetch = FetchType.LAZY)
public UserProfile getUserProfile(){ ... }
Run Code Online (Sandbox Code Playgroud) 有Foo
一个@Version
列的实体.如果我想删除它,我希望Spring Data JPA和/或Hibernate检查@Version
列的当前值是否与数据库中的值匹配.如果没有,则应拒绝删除.这与预期的分离实体一起工作:
@Transactional
public void delete(Foo foo) {
fooRepository.delete(foo); // throws ObjectOptimisticLockingFailureException
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我首先从存储库加载实体,然后使用不同的版本在同一事务中删除它,则无论@Version
列的值如何,删除都会通过:
@Transactional
public void delete(int fooId, long version) {
Foo foo = fooRepository.findOne(fooId);
foo.setVersion(version);
fooRepository.delete(foo); // passes regardless of value of version
}
Run Code Online (Sandbox Code Playgroud)
当我查看Hibernate调试输出时,执行版本比较(delete from foo where id=? and version=?
)但不是我期望的效果.
我错过了什么?
我已经了解到Hibernate在为您提供查询结果时不返回实际实体类的实例,而是返回一个"代理"实例,该实例是从您的实际实体类中动态子类的.我理解这种行为的原因,因为它允许实现延迟初始化.但是,我对这些代理类的实现细节还有一些问题没有答案:
当我使用getter时,懒惰的获取字段是否会被加载?如果我在我的equals
或hashCode
方法中使用该字段该怎么办?这些方法的执行是否会导致NullPointerException
我之前没有调用此字段的getter?
Hibernate在触发初始化时如何初始化字段?它是否执行我在实体类中定义的字段的setter方法,还是通过反射或类似的方式将值直接赋值给变量?
我有一个.bat
启动java程序的Windows 文件.为方便起见,我创建了一个Eclipse外部工具配置,以便直接从IDE启动它,并从Eclipse控制台读取其标准输出.
但是,当我在Console视图中使用terminate按钮(红色方块)从Eclipse终止进程时,程序仍在运行.
如何从Eclipse中删除它(没有创建一个单独的启动配置来搜索它并以编程方式杀死它)?
我有Employee
(父母)和Emp_Contacts
(孩子).只有Employee
类具有单向映射.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Size(min=3, max=50)
@Column(name = "NAME", nullable = false)
private String name;
...
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "emp_id")
private Set<Emp_Contacts> contacts;
...getters and setters...
Run Code Online (Sandbox Code Playgroud)
我的Emp_Contacts
情况如下:
@Entity
@Table(name = "Emp_Contacts") …
Run Code Online (Sandbox Code Playgroud) 考虑类Account
,RealAccount
和VirtualAccount
,以及Operation
:
class Account { }
class RealAccount extends Account { String name; }
class VirtualAccount extends Account { }
class Operation { Account account; }
Run Code Online (Sandbox Code Playgroud)
这意味着:
RealAccount
一个叫做的字段name
.Operation
的帐户可以是RealAccount
或VirtualAccount
.我想查询Operation
属于RealAccount
具有特定名称的所有s :
session.createCriteria(Operation.class)
.createAlias("account", "_account")
.add(Restrictions.eq("_account.name", "Alice"))
.list();
Run Code Online (Sandbox Code Playgroud)
这失败了.
我的问题:使用"旧"的Hibernate API的标准,我怎么可以查询该账户名称只存在当Operation
的帐户是RealAccount
?也许是一些包容DetachedCriteria
和Subqueries
......
我希望有多对多的关系.之间PLAYER
和PRIVILEGE
.你能帮我修一下我的.xml配置吗?
预期结果:
我希望能够执行:String hql = "from Player as p right outer join p.privilages as priv";
实际: 到目前为止我得到:
org.hibernate.MappingException:外键(FK8CD18EE134F64423:PLAYER [ID]))必须与引用的主键具有相同的列数(PRIVILAGE [ID,PRIVILAGE])
<hibernate-mapping>
<class name="model.Privilage" table="PRIVILAGE">
<id name="id" type="int" >
<column name="ID" precision="5" scale="0"/>
<generator class="increment"/>
</id>
<set name="players" table="PLAYER"
inverse="false" lazy="true" fetch="select" cascade="all" >
<key>
<column name="ID"/>
</key>
<many-to-many entity-name="model.Player">
<column name="ID" not-null="true" />
</many-to-many>
</set>
<property name="privilage" type="string">
<column name="PRIVILAGE" length="20" not-null="true" />
</property>
</class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)
和
<class name="model.Player" table="PLAYER">
<id name="playerId" type="int" > …
Run Code Online (Sandbox Code Playgroud) 我有两张单对多关系的表
类服务提供者{
...
@OneToMany(fetch=FetchType.EAGER,mappedBy="serviceProvider", cascade={CascadeType.ALL,CascadeType.REMOVE},orphanRemoval = true) @OnDelete(action=OnDeleteAction.CASCADE) 私有列表 serviceCenters; ...
}
类服务中心详细信息{
... //双向多对一关联到ServiceProviderDomainMap @ManyToOne @JoinColumn(name="SERVICE_PROVIDER_ID") private ServiceProvider serviceProvider;
...
}
我正在尝试删除提供行。但我收到以下错误:
引起:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:无法删除或更新父行:外键约束失败(fixoline
. service_center_details
,CONSTRAINT FK_qvahoxeovx9vmwl6mcu2c0lyw
FOREIGN KEY(SERVICE_PROVIDER_ID
)REFERENCES service_provider
(ID
))
下面是我正在尝试的方式
Run Code Online (Sandbox Code Playgroud)String hql = "DELETE FROM ServiceProvider WHERE id = :providerId"; Query query = sessionFactory.getCurrentSession().createQuery(hql); query.setParameter("providerId",providerId); int result = query.executeUpdate();
有人可以帮忙解决吗?
我有一个简单的类用于说明目的:
public class Test {
public int test1() {
int result = 100;
result = 200;
return result;
}
public int test2() {
return 200;
}
}
Run Code Online (Sandbox Code Playgroud)
编译器生成的字节码(检查者javap -c Test.class
)如下:
public int test1();
Code:
0: bipush 100
2: istore_1
3: sipush 200
6: istore_1
7: iload_1
8: ireturn
public int test2();
Code:
0: sipush 200
3: ireturn
Run Code Online (Sandbox Code Playgroud)
为什么编译器没有将test1
方法优化为为该方法生成的相同字节码test2
?我希望它至少可以避免result
变量的冗余初始化,因为很容易得出结论100
根本没有使用该值.
我用Eclipse编译器和javac
.
javac
version 1.8.0_72
:,与Java一起作为JDK的一部分安装:
Java(TM) SE Runtime Environment (build …
Run Code Online (Sandbox Code Playgroud) 第一个例子:
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) throws Exception {
try {
throw new RuntimeException(new NullPointerException("NPE"));
} catch (RuntimeException e) {
logger.error("Error:", e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Error:
java.lang.RuntimeException: java.lang.NullPointerException: NPE
at Main.main(Main.java:10)
Run Code Online (Sandbox Code Playgroud)
在第二个例子中,我们只是添加一条消息RuntimeException
:
throw new RuntimeException("RTE", new NullPointerException("NPE"));
Run Code Online (Sandbox Code Playgroud)
输出:
Error:
java.lang.RuntimeException: RTE
at Main.main(Main.java:10)
Run Code Online (Sandbox Code Playgroud)
为什么NullPointerException
不记录这种情况?
注意:e.printStackTrace()
在两种情况下都会打印两个例外:
java.lang.RuntimeException: RTE
at Main.main(Main.java:10)
Caused by: java.lang.NullPointerException: NPE
... 1 more
Run Code Online (Sandbox Code Playgroud)
版本:
slf4j-api: 1.7.12
slf4j-log4j12: 1.7.12
log4j: …
Run Code Online (Sandbox Code Playgroud) java ×9
hibernate ×6
jpa ×2
batch-file ×1
bytecode ×1
eclipse ×1
exception ×1
fetch ×1
foreign-keys ×1
jackson ×1
javac ×1
log4j ×1
logging ×1
many-to-many ×1
mysql ×1
proxy ×1
slf4j ×1
spring ×1
spring-boot ×1
spring-mvc ×1
subquery ×1