我正在使用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_qvahoxeovx9vmwl6mcu2c0lywFOREIGN 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.
javacversion 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